ReactOS 0.4.15-dev-7958-gcd0bb1a
util.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Drivers
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/sac/driver/util.c
5 * PURPOSE: Driver for the Server Administration Console (SAC) for EMS
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "sacdrv.h"
12
13#include <ndk/rtlfuncs.h>
14
15/* GLOBALS ********************************************************************/
16
19
21
30
33
36
37/* FUNCTIONS ******************************************************************/
38
42 IN PCHAR Utf8Buffer,
43 OUT PWCHAR Utf8Value)
44{
45 ULONG i;
46
47 /* Find out how many valid characters we have in the buffer */
48 i = 0;
49 while (Utf8Buffer[i++] && (i < 3));
50
51 /* If we have at least 3, shift everything by a byte */
52 if (i >= 3)
53 {
54 /* The last input character goes at the end */
55 Utf8Buffer[0] = Utf8Buffer[1];
56 Utf8Buffer[1] = Utf8Buffer[2];
57 Utf8Buffer[2] = Utf8Char;
58 }
59 else
60 {
61 /* We don't have more than 3 characters, place the input at the index */
62 Utf8Buffer[i] = Utf8Char;
63 }
64
65 /* Print to debugger */
66 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SacTranslateUtf8ToUnicode - About to decode the UTF8 buffer.\n");
67 SAC_DBG(SAC_DBG_ENTRY_EXIT, " UTF8[0]: 0x%02lx UTF8[1]: 0x%02lx UTF8[2]: 0x%02lx\n",
68 Utf8Buffer[0],
69 Utf8Buffer[1],
70 Utf8Buffer[2]);
71
72 /* Is this a simple ANSI character? */
73 if (!(Utf8Char & 0x80))
74 {
75 /* Return it as Unicode, nothing left to do */
76 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SACDRV: SacTranslateUTf8ToUnicode - Case1\n");
77 *Utf8Value = (WCHAR)Utf8Char;
78 Utf8Buffer[0] = Utf8Buffer[1];
79 Utf8Buffer[1] = Utf8Buffer[2];
80 Utf8Buffer[2] = UNICODE_NULL;
81 return TRUE;
82 }
83
84 /* Anything else is not yet supported */
86 return FALSE;
87}
88
92 IN ULONG SourceBufferLength,
93 OUT PCHAR DestinationBuffer,
95 OUT PULONG UTF8Count,
96 OUT PULONG ProcessedCount)
97{
98 *UTF8Count = 0;
99 *ProcessedCount = 0;
100
101 while ((*SourceBuffer) &&
102 (*UTF8Count < DestinationBufferSize) &&
103 (*ProcessedCount < SourceBufferLength))
104 {
105 if (*SourceBuffer & 0xFF80)
106 {
107 if (*SourceBuffer & 0xF800)
108 {
109 if ((*UTF8Count + 3) >= DestinationBufferSize) break;
110 DestinationBuffer[*UTF8Count] = ((*SourceBuffer >> 12) & 0xF) | 0xE0;
111 ++*UTF8Count;
112 DestinationBuffer[*UTF8Count] = ((*SourceBuffer >> 6) & 0x3F) | 0x80;
113 }
114 else
115 {
116 if ((*UTF8Count + 2) >= DestinationBufferSize) break;
117 DestinationBuffer[*UTF8Count] = ((*SourceBuffer >> 6) & 31) | 0xC0;
118 }
119 ++*UTF8Count;
120 DestinationBuffer[*UTF8Count] = (*SourceBuffer & 0x3F) | 0x80;
121 }
122 else
123 {
124 DestinationBuffer[*UTF8Count] = (*SourceBuffer & 0x7F);
125 }
126
127 ++*UTF8Count;
128 ++*ProcessedCount;
129 ++SourceBuffer;
130 }
131
132 ASSERT(*ProcessedCount <= SourceBufferLength);
133 ASSERT(*UTF8Count <= DestinationBufferSize);
134 return TRUE;
135}
136
137PWCHAR
138NTAPI
139GetMessage(IN ULONG MessageIndex)
140{
141 PSAC_MESSAGE_ENTRY MessageEntry;
142 ULONG i;
143 PWCHAR MessageData = NULL;
144
145 /* Loop all cached messages */
146 for (i = 0; i < GlobalMessageTableCount; i++)
147 {
148 /* Check if this one matches the index */
149 MessageEntry = &GlobalMessageTable[i];
150 if (MessageEntry->Index == MessageIndex)
151 {
152 /* It does, return the buffer */
153 MessageData = MessageEntry->Buffer;
154 break;
155 }
156 }
157
158 /* We should always find it */
159 if (!MessageData) ASSERT(FALSE);
160 return MessageData;
161}
162
164NTAPI
166{
167 ULONG ProcessedCount, Utf8Count, i;
169
170 /* Call the translator routine */
172 wcslen(String),
175 &Utf8Count,
176 &ProcessedCount))
177 {
178 /* Loop every character */
179 for (i = 0; i < Utf8Count; i++)
180 {
181 /* Send it to the terminal */
184 sizeof(Utf8ConversionBuffer[i]),
185 NULL,
186 NULL);
187 if (!NT_SUCCESS(Status)) break;
188 }
189 }
190 else
191 {
192 /* Conversion failed */
194 }
195
196 /* All done */
197 return Status;
198}
199
200VOID
201NTAPI
202SacFormatMessage(IN PWCHAR FormattedString,
203 IN PWCHAR MessageString,
204 IN ULONG MessageSize)
205{
206 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Entering.\n");
207
208 /* Check if any of the parameters are NULL or zero */
209 if (!(MessageString) || !(FormattedString) || !(MessageSize))
210 {
211 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Exiting with invalid parameters.\n");
212 return;
213 }
214
215 /* Keep going as long as there's still characters */
216 while ((MessageString[0]) && (MessageSize))
217 {
218 /* Is it a non-formatting character? */
219 if (MessageString[0] != L'%')
220 {
221 /* Just write it back into the buffer and keep going */
222 *FormattedString++ = MessageString[0];
223 MessageString++;
224 }
225 else
226 {
227 /* Go over the format characters we recognize */
228 switch (MessageString[1])
229 {
230 case L'0':
231 *FormattedString = UNICODE_NULL;
232 return;
233
234 case L'%':
235 *FormattedString++ = L'%';
236 break;
237
238 case L'\\':
239 *FormattedString++ = L'\r';
240 *FormattedString++ = L'\n';
241 break;
242
243 case L'r':
244 *FormattedString++ = L'\r';
245 break;
246
247 case L'b':
248 *FormattedString++ = L' ';
249 break;
250
251 case L'.':
252 *FormattedString++ = L'.';
253 break;
254
255 case L'!':
256 *FormattedString++ = L'!';
257 break;
258
259 default:
260 /* Only move forward one character */
261 MessageString--;
262 break;
263 }
264
265 /* Move forward two characters */
266 MessageString += 2;
267 }
268
269 /* Move to the next character*/
270 MessageSize--;
271 }
272
273 /* All done */
274 *FormattedString = UNICODE_NULL;
275 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Exiting.\n");
276}
277
279NTAPI
281{
282 NTSTATUS Status, Status2;
283 ULONG MessageId, TotalLength, TextSize, i;
285 PMESSAGE_RESOURCE_ENTRY MessageEntry;
286 PAGED_CODE();
287 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n");
288
289 /* Nothing to do if we already have a table */
291 if (GlobalMessageTable) goto Exit;
292
293 /* Loop through up to 200 messages */
294 TotalLength = 0;
295 for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
296 {
297 /* Find this message ID in the string table*/
298 Status2 = RtlFindMessage(ImageBase,
299 11,
301 MessageId,
302 &MessageEntry);
303 if (NT_SUCCESS(Status2))
304 {
305 /* Make sure it's Unicode */
306 ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE);
307
308 /* Remove the space taken up by the OS header, and add our own */
309 TotalLength += MessageEntry->Length -
311 sizeof(SAC_MESSAGE_ENTRY);
312
313 /* One more in the table */
315 }
316 }
317
318 /* We should've found at least one message... */
319 if (!TotalLength)
320 {
321 /* Bail out otherwise */
322 SAC_DBG(SAC_DBG_INIT, "SAC PreloadGlobalMessageTable: No Messages.\n");
324 goto Exit;
325 }
326
327 /* Allocate space for the buffers and headers */
330 {
331 /* Bail out if we couldn't allocate it */
333 goto Exit;
334 }
335
336 /* All the buffers are going to be at the end of the table */
338
339 /* Now loop over our entries again */
340 for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
341 {
342 /* Make sure the message is still there...! */
343 Status2 = RtlFindMessage(ImageBase,
344 11,
346 MessageId,
347 &MessageEntry);
348 if (NT_SUCCESS(Status2))
349 {
350 /* Write the entry in the message table*/
351 GlobalMessageTable[i].Index = MessageId;
353
354 /* The structure includes the size of the header, elide it */
355 TextSize = MessageEntry->Length -
357
358 /* Format the message into the entry. It should be same or smaller */
359 SacFormatMessage(StringBuffer, (PWCHAR)MessageEntry->Text, TextSize);
360 ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize);
361
362 /* Move to the next buffer space */
363 StringBuffer += (TextSize / sizeof(WCHAR));
364
365 /* Move to the next entry, make sure the status is full success */
366 i++;
368 }
369 }
370
371Exit:
372 /* All done, return the status code */
373 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting with status 0x%0x\n", Status);
374 return Status;
375}
376
378NTAPI
380{
381 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Entering.\n");
382
383 /* Free the table if one existed */
385
386 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting\n");
387 return STATUS_SUCCESS;
388}
389
391NTAPI
395{
401 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Entering.\n");
404
405 /* Open the specified key */
410 NULL,
411 NULL);
412 Status = ZwOpenKey(&Handle,
415 if (!NT_SUCCESS(Status))
416 {
417 /* Bail out on failure */
418 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwOpenKey: %X.\n", Status);
419 return Status;
420 }
421
422 /* Query the size of the key */
424 Status = ZwQueryValueKey(Handle,
427 NULL,
428 0,
429 &ResultLength);
430 if (!ResultLength)
431 goto Quit;
432
433 /* Allocate the buffer for the partial info structure and our integer data */
434 ResultLength += sizeof(ULONG);
436 if (!*Buffer)
437 {
438 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed allocation\n");
439 goto Quit;
440 }
441
442 /* Now read the data */
443 Status = ZwQueryValueKey(Handle,
446 *Buffer,
448 &ResultLength);
449 if (!NT_SUCCESS(Status))
450 {
451 /* Free the buffer if we couldn't read the data */
452 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwQueryValueKey: %X.\n", Status);
454 }
455
456Quit:
457 /* Close the handle and exit */
459 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Exiting.\n");
460 return Status;
461}
462
464NTAPI
467 IN ULONG Type,
468 IN PVOID Data,
470{
475 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Entering.\n");
479
480 /* Open the specified key */
485 NULL,
486 NULL);
487 Status = ZwOpenKey(&Handle,
490 if (!NT_SUCCESS(Status))
491 {
492 /* Bail out on failure */
493 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: failed ZwOpenKey: %X.\n", Status);
494 return Status;
495 }
496
497 /* Set the specified value */
499 Status = ZwSetValueKey(Handle, &DestinationString, 0, Type, Data, DataSize);
500 if (!NT_SUCCESS(Status))
501 {
502 /* Print error on failure */
503 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: failed ZwSetValueKey: %X.\n", Status);
504 }
505
506 /* Close the handle and exit */
508 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n");
509 return Status;
510}
511
513NTAPI
516{
519 CHECK_PARAMETER2(PartialInfo);
520
521 /* Allocate space for registry data */
522 *Buffer = SacAllocatePool(PartialInfo->DataLength, GLOBAL_BLOCK_TAG);
523 if (*Buffer)
524 {
525 /* Copy the data into the buffer */
526 RtlCopyMemory(*Buffer, PartialInfo->Data, PartialInfo->DataLength);
527 }
528 else
529 {
530 /* Set the correct error code */
531 SAC_DBG(SAC_DBG_UTIL, "SAC CopyRegistryValueBuffer: Failed ALLOCATE.\n");
533 }
534
535 /* Return the result */
536 return Status;
537}
538
540NTAPI
542 IN PWCHAR ExtraData)
543{
545 SIZE_T Size;
546 PWCHAR p;
548
549 /* Start by believing the world is beautiful */
551
552 /* First, the header */
553 Size = wcslen(L"<machine-info>\r\n");
554
555 /* Do we have a machine name? */
557 {
558 /* Go and add it in */
560 Size += wcslen(L"<name>%s</name>\r\n");
561 }
562
563 /* Do we have a GUID? */
565 {
566 /* Go and add it in */
568 Size += wcslen(L"<guid>%s</guid>\r\n");
569 }
570
571 /* Do we know the processor? */
573 {
574 /* Go and add it in */
576 Size += wcslen(L"<processor-architecture>%s</processor-architecture>\r\n");
577 }
578
579 /* Do we have the version? */
581 {
582 /* Go and add it in */
584 Size += wcslen(L"<os-version>%s</os-version>\r\n");
585 }
586
587 /* Do we have the build? */
589 {
590 /* Go and add it in */
592 Size += wcslen(L"<os-build-number>%s</os-build-number>\r\n");
593 }
594
595 /* Do we have the product type? */
597 {
598 /* Go and add it in */
600 Size += wcslen(L"<os-product>%s</os-product>\r\n");
601 }
602
603 /* Do we have a service pack? */
605 {
606 /* Go and add it in */
608 Size += wcslen(L"<os-service-pack>%s</os-service-pack>\r\n");
609 }
610
611 /* Anything else we need to know? Add it in too */
612 if (ExtraData) Size += wcslen(ExtraData);
613
614 /* Finally, add the footer */
615 Size += wcslen(L"</machine-info>\r\n");
616
617 /* Convert to bytes and add a NULL */
618 Size += sizeof(ANSI_NULL);
619 Size *= sizeof(WCHAR);
620
621 /* Allocate space for the buffer */
623 *Buffer = p;
624 if (!p) return STATUS_NO_MEMORY;
625
626 wcscpy(p, L"<machine-info>\r\n");
627 p += wcslen(L"<machine-info>\r\n");
628
630 {
631 p += swprintf(p,
632 L"<name>%s</name>\r\n",
634 }
635
637 {
638 p += swprintf(p,
639 L"<guid>%s</guid>\r\n",
641 }
642
644 {
645 p += swprintf(p,
646 L"<processor-architecture>%s</processor-architecture>\r\n",
648 }
649
651 {
652 p += swprintf(p,
653 L"<os-version>%s</os-version>\r\n",
655 }
656
658 {
659 p += swprintf(p,
660 L"<os-build-number>%s</os-build-number>\r\n",
662 }
663
665 {
666 p += swprintf(p,
667 L"<os-product>%s</os-product>\r\n",
669 }
670
672 {
673 p += swprintf(p,
674 L"<os-service-pack>%s</os-service-pack>\r\n",
676 }
677
678 if (ExtraData)
679 {
680 wcscpy(p, ExtraData);
681 p += wcslen(ExtraData);
682 }
683
684 wcscpy(p, L"</machine-info>\r\n");
685 SAC_DBG(SAC_DBG_ENTRY_EXIT, "MachineInformation: %S\n", *Buffer);
686 ASSERT((((ULONG)wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size);
687 return Status;
688}
689
690VOID
691NTAPI
693{
695 PWCHAR GuidString, MajorVersion, ServicePack, BuildNumber, MessageBuffer;
696 PWCHAR ProductType;
697 ULONG SuiteTypeMessage;
698 BOOLEAN SetupInProgress = FALSE;
699 GUID SystemGuid;
700 SIZE_T RealSize, Size, OutputSize;
702 RTL_OSVERSIONINFOEXW VersionInformation;
703 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n");
704
705 /* Don't do anything if we already queried this */
707 {
708 SAC_DBG(SAC_DBG_MACHINE, "SAC Initialize Machine Information:: MachineInformationBuffer already initialized.\n");
709 return;
710 }
711
712 /* Allocate the machine information */
716 {
717 goto Fail;
718 }
719
720 /* Zero it out for now */
722
723 /* Query OS version */
724 RtlZeroMemory(&VersionInformation, sizeof(VersionInformation));
725 VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation);
726 Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&VersionInformation);
727 if (!NT_SUCCESS(Status))
728 {
729 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (2).\n");
730 goto Fail;
731 }
732
733 /* Check if setup is in progress */
734 Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\Setup",
735 L"SystemSetupInProgress",
736 &PartialInfo);
737 if (NT_SUCCESS(Status))
738 {
739 /* The key is there, is the value set? */
740 if (*(PULONG)PartialInfo->Data) SetupInProgress = TRUE;
741 SacFreePool(PartialInfo);
742 if (SetupInProgress)
743 {
744 /* Yes, so we'll use a special hostname to identify this */
745 MessageBuffer = GetMessage(SAC_UNINITIALIZED_MSG);
746 Size = wcslen(MessageBuffer);
747 ASSERT(Size > 0);
748 RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
749
750 /* Make room for it and copy it in there */
754 {
755 wcscpy(MachineInformation->MachineName, MessageBuffer);
756 }
757 }
758 }
759
760 /* If we are not in setup mode, or if we failed to check... */
761 if (!SetupInProgress)
762 {
763 /* Query the computer name */
764 Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\"
765 L"CurrentControlSet\\Control\\"
766 L"ComputerName\\ComputerName",
767 L"ComputerName",
768 &PartialInfo);
769 if (!NT_SUCCESS(Status))
770 {
771 /* It's not critical, but we won't have it */
772 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Failed to get machine name.\n");
773 }
774 else
775 {
776 /* We have the name, copy it from the registry */
779 PartialInfo);
780 SacFreePool(PartialInfo);
781 if (!NT_SUCCESS(Status))
782 {
783 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (20).\n");
784 goto Fail;
785 }
786 }
787 }
788
789 /* Next step, try to get the machine GUID */
790 RtlZeroMemory(&SystemGuid, sizeof(SystemGuid));
791 OutputSize = sizeof(SystemGuid);
793 NULL,
794 0,
795 &SystemGuid,
796 &OutputSize);
797 if (!NT_SUCCESS(Status))
798 {
799 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Failed to get Machine GUID.\n");
800 }
801 else
802 {
803 /* We have it -- make room for it */
805 if (!GuidString)
806 {
807 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (31).\n");
808 goto Fail;
809 }
810
811 /* Build the string with the GUID in it, and save the ppointer to it */
813 L"%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
814 SystemGuid.Data1,
815 SystemGuid.Data2,
816 SystemGuid.Data3,
817 SystemGuid.Data4[0],
818 SystemGuid.Data4[1],
819 SystemGuid.Data4[2],
820 SystemGuid.Data4[3],
821 SystemGuid.Data4[4],
822 SystemGuid.Data4[5],
823 SystemGuid.Data4[6],
824 SystemGuid.Data4[7]);
826 }
827
828 /* Next, query the processor architecture */
829 Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\"
830 L"CurrentControlSet\\Control\\"
831 L"Session Manager\\Environment",
832 L"PROCESSOR_ARCHITECTURE",
833 &PartialInfo);
834 if (!NT_SUCCESS(Status))
835 {
836 /* It's not critical, but we won't have it */
837 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (30).\n");
838 }
839 else
840 {
841 /* We have it! Copy the value from the registry */
843 ProcessorArchitecture,
844 PartialInfo);
845 SacFreePool(PartialInfo);
846 if (!NT_SUCCESS(Status))
847 {
848 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (30).\n");
849 goto Fail;
850 }
851 }
852
853 /* Now allocate a buffer for the OS version number */
855 if (!MajorVersion)
856 {
857 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (50).\n");
858 goto Fail;
859 }
860
861 /* Build the buffer and set a pointer to it */
863 L"%d.%d",
864 VersionInformation.dwMajorVersion,
865 VersionInformation.dwMinorVersion);
867
868 /* Now allocate a buffer for the OS build number */
870 if (!BuildNumber)
871 {
872 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (60).\n");
873 goto Fail;
874 }
875
876 /* Build the buffer and set a pointer to it */
877 swprintf(BuildNumber, L"%d", VersionInformation.dwBuildNumber);
879
880 /* Now check what kind of SKU this is */
882 {
883 SuiteTypeMessage = SAC_DATACENTER_SUITE_MSG;
884 }
885 else if (ExVerifySuite(EmbeddedNT))
886 {
887 SuiteTypeMessage = SAC_EMBEDDED_SUITE_MSG;
888 }
889 else if (ExVerifySuite(Enterprise))
890 {
891 SuiteTypeMessage = SAC_ENTERPRISE_SUITE_MSG;
892 }
893 else
894 {
895 /* Unknown or perhaps a client SKU */
896 SuiteTypeMessage = SAC_NO_SUITE_MSG;
897 }
898
899 /* Get the string that corresponds to the SKU type */
900 MessageBuffer = GetMessage(SuiteTypeMessage);
901 if (!MessageBuffer)
902 {
903 /* We won't have it, but this isn't critical */
904 SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed to get product type.\n");
905 }
906 else
907 {
908 /* Calculate the size we need to hold the string */
909 Size = wcslen(MessageBuffer);
910 ASSERT(Size > 0);
911 RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
912
913 /* Allocate a buffer for it */
914 ProductType = SacAllocatePool(RealSize, GLOBAL_BLOCK_TAG);
915 if (!ProductType)
916 {
917 SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed product type memory allocation.\n");
918 goto Fail;
919 }
920
921 /* Copy the string and set the pointer */
922 RtlCopyMemory(ProductType, MessageBuffer, RealSize);
923 MachineInformation->ProductType = ProductType;
924 }
925
926 /* Check if this is a SP version or RTM version */
927 if (VersionInformation.wServicePackMajor)
928 {
929 /* This is a service pack, allocate a buffer for the version */
930 ServicePack = SacAllocatePool(0x18, GLOBAL_BLOCK_TAG);
931 if (ServicePack)
932 {
933 /* Build the buffer and set a pointer to it */
934 swprintf(ServicePack,
935 L"%d.%d",
936 VersionInformation.wServicePackMajor,
937 VersionInformation.wServicePackMinor);
938 MachineInformation->ServicePack = ServicePack;
939
940 /* We've collected all the machine info and are done! */
941 return;
942 }
943
944 /* This is the failure path */
945 SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed service pack memory allocation.\n");
946 }
947 else
948 {
949 /* Get a generic string that indicates there's no service pack */
950 MessageBuffer = GetMessage(SAC_NO_DATA_MSG);
951 Size = wcslen(MessageBuffer);
952 ASSERT(Size > 0);
953 RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
954
955 /* Allocate memory for the "no service pack" string */
956 ServicePack = SacAllocatePool(RealSize, GLOBAL_BLOCK_TAG);
957 if (ServicePack)
958 {
959 /* Copy the buffer and set a pointer to it */
960 RtlCopyMemory(ServicePack, MessageBuffer, RealSize);
961 MachineInformation->ServicePack = ServicePack;
962
963 /* We've collected all the machine info and are done! */
964 return;
965 }
966
967 SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed service pack memory allocation.\n");
968 }
969
970Fail:
971 /* In the failure path, always cleanup the machine information buffer */
973 {
975 }
976 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n");
977}
978
980NTAPI
982{
985
986 /* Assume success and read the key */
987 *Permission = TRUE;
988 Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacdrv",
989 L"DisableCmdSessions",
990 &Dummy);
992 {
993 /* The default is success */
995 }
996 else
997 {
998 /* Only if the key is present and set, do we disable permission */
999 if (NT_SUCCESS(Status)) *Permission = FALSE;
1000 }
1001
1002 /* Return status */
1003 return Status;
1004}
1005
1007NTAPI
1009{
1012 PULONG Data;
1013
1014 /* Read the service start type*/
1015 Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr",
1016 L"Start",
1017 &Buffer);
1018 if (!NT_SUCCESS(Status)) return Status;
1019
1020 /* If there's no start type, fail, as this is unusual */
1021 if (!Buffer) return STATUS_UNSUCCESSFUL;
1022
1023 /* Read the value */
1026 if (!NT_SUCCESS(Status)) return Status;
1027
1028 /* Check what the current start type is */
1029 switch (*Data)
1030 {
1031 /* It's boot, system, or disabled */
1032 case 1:
1033 case 2:
1034 case 4:
1035 /* Leave it as is */
1036 return Status;
1037
1038 case 3:
1039
1040 /* It's set to automatic, set it to system instead */
1041 *Data = 2;
1042 Status = SetRegistryValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr",
1043 L"Start",
1044 REG_DWORD,
1045 Data,
1046 sizeof(ULONG));
1047 if (!NT_SUCCESS(Status))
1048 {
1049 SAC_DBG(SAC_DBG_INIT, "SAC ImposeSacCmdServiceStartTypePolicy: Failed SetRegistryValue: %X\n", Status);
1050 }
1051 break;
1052
1053 default:
1054 ASSERT(FALSE);
1055 }
1056
1057 return Status;
1058}
1059
1060VOID
1061NTAPI
1063{
1064 /* Check if we were already initialized */
1066 {
1067 /* Full state expected */
1071
1072 /* Dereference each wait object in turn */
1074 {
1076 }
1077
1079 {
1081 }
1082
1084 {
1086 }
1087 }
1088
1089 /* Claer everything */
1097
1098 /* Reset state */
1100}
1101
1103NTAPI
1105{
1106 PWCHAR XmlBuffer;
1108 SIZE_T Length, HeaderLength, TotalLength;
1110 ULONG i;
1111
1112 /* Create the XML buffer and make sure it's OK */
1116
1117 /* Compute the sizes and allocate a buffer for it */
1118 Length = wcslen(XmlBuffer);
1119 HeaderLength = strlen("MACHINEINFO");
1120 TotalLength = HeaderLength +
1121 Length +
1122 sizeof(*BsBuffer) +
1123 2 * sizeof(ANSI_NULL);
1126
1127 /* Copy the XML property name */
1128 strcpy((PCHAR)BsBuffer->Data, "MACHINEINFO");
1129 BsBuffer->ValueIndex = HeaderLength + sizeof(ANSI_NULL);
1130
1131 /* Copy the data and NULL-terminate it */
1132 for (i = 0; i < Length; i++)
1133 {
1134 BsBuffer->Data[BsBuffer->ValueIndex + i] = XmlBuffer[i];
1135 }
1136 BsBuffer->Data[BsBuffer->ValueIndex + i] = ANSI_NULL;
1137
1138 /* Let the OS save the buffer for later */
1140 BsBuffer,
1142 NULL,
1143 NULL);
1144
1145 /* Failure or not, we don't need this anymore */
1146 SacFreePool(BsBuffer);
1147 SacFreePool(XmlBuffer);
1148
1149 /* Return the result */
1150 SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information: Exiting.\n");
1151 return Status;
1152}
1153
1154VOID
1155NTAPI
1157{
1159
1160 /* Free every cached string of machine information */
1168}
1169
1170BOOLEAN
1171NTAPI
1173 OUT PVOID *WaitObject,
1174 OUT PVOID *ActualWaitObject)
1175{
1176 PVOID Object;
1179
1180 /* Reference the object */
1183 NULL,
1184 KernelMode,
1185 &Object,
1186 NULL);
1187 *WaitObject = Object;
1188 if (!NT_SUCCESS(Status))
1189 {
1190 SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: Unable to reference event object (%lx)\n", Status);
1191 return FALSE;
1192 }
1193
1194 /* Check if the object itself is NOT being used */
1196 if (ObjectType->TypeInfo.UseDefaultObject == FALSE)
1197 {
1198 /* Get the actual object that's being used for the wait */
1199 *ActualWaitObject = (PVOID)((ULONG_PTR)Object +
1200 (ULONG_PTR)ObjectType->DefaultObject);
1201 return TRUE;
1202 }
1203
1204 /* Drop the reference we took */
1205 SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: event object not waitable!\n");
1206 ObDereferenceObject(*WaitObject);
1207 return FALSE;
1208}
1209
1211NTAPI
1213{
1214 /* Check if nothing's been produced yet */
1216 {
1218 }
1219
1220 /* Consume the produced character and clear it*/
1223
1224 /* Advance the index and return success */
1228 return STATUS_SUCCESS;
1229}
1230
1231ULONG
1232NTAPI
1234{
1235 ULONG LineCount = 0;
1236 PWCHAR Buffer;
1237
1238 /* Get the message buffer */
1239 Buffer = GetMessage(MessageIndex);
1240 if (Buffer)
1241 {
1242 /* Scan it looking for new lines, and increment the count each time */
1243 while (*Buffer) if (*Buffer++ == L'\n') ++LineCount;
1244 }
1245
1246 /* Return the line count */
1247 return LineCount;
1248}
1249
1250ULONG
1252 IN PWCHAR pwch,
1253 IN PCHAR pch,
1255 )
1256{
1258}
1259
1260BOOLEAN
1263 )
1264{
1265 return FALSE;
1266}
1267
1270 VOID
1271 )
1272{
1274}
1275
1279{
1281}
1282
1285 IN PWCHAR SourceStr,
1287 IN PWCHAR InsertStr,
1288 OUT PWCHAR pDestStr
1289 )
1290{
1292}
1293
1296 IN PVOID Object,
1297 IN PKEVENT SetupCmdEvent[]
1298 )
1299{
1301}
1302
1306 )
1307{
1309}
#define PAGED_CODE()
unsigned char BOOLEAN
Type
Definition: Type.h:7
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
char * Text
Definition: combotst.c:136
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
#define swprintf
Definition: precomp.h:40
NTSTATUS TranslateMachineInformationText(IN PWCHAR Buffer)
Definition: util.c:1277
ULONG GlobalMessageTableCount
Definition: util.c:32
NTSTATUS NTAPI UTF8EncodeAndSend(IN PWCHAR String)
Definition: util.c:165
BOOLEAN IsCmdEventRegistrationProcess(IN PFILE_OBJECT FileObject)
Definition: util.c:1261
BOOLEAN NTAPI VerifyEventWaitable(IN HANDLE Handle, OUT PVOID *WaitObject, OUT PVOID *ActualWaitObject)
Definition: util.c:1172
NTSTATUS NTAPI ImposeSacCmdServiceStartTypePolicy(VOID)
Definition: util.c:1008
NTSTATUS NTAPI CopyRegistryValueData(IN PVOID *Buffer, IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo)
Definition: util.c:514
PSAC_MACHINE_INFO MachineInformation
Definition: util.c:20
NTSTATUS CopyAndInsertStringAtInterval(IN PWCHAR SourceStr, IN ULONG Interval, IN PWCHAR InsertStr, OUT PWCHAR pDestStr)
Definition: util.c:1284
ULONG Utf8ConversionBufferSize
Definition: util.c:18
VOID NTAPI SacFormatMessage(IN PWCHAR FormattedString, IN PWCHAR MessageString, IN ULONG MessageSize)
Definition: util.c:202
PKEVENT RequestSacCmdFailureEventWaitObjectBody
Definition: util.c:27
PVOID RequestSacCmdSuccessEventObjectBody
Definition: util.c:24
NTSTATUS NTAPI PreloadGlobalMessageTable(IN PVOID ImageBase)
Definition: util.c:280
LONG SerialPortProducerIndex
Definition: util.c:34
NTSTATUS NTAPI RegisterBlueScreenMachineInformation(VOID)
Definition: util.c:1104
BOOLEAN NTAPI SacTranslateUtf8ToUnicode(IN CHAR Utf8Char, IN PCHAR Utf8Buffer, OUT PWCHAR Utf8Value)
Definition: util.c:41
VOID NTAPI FreeMachineInformation(VOID)
Definition: util.c:1156
PFILE_OBJECT ServiceProcessFileObject
Definition: util.c:28
PCHAR SerialPortBuffer
Definition: util.c:35
LONG SerialPortConsumerIndex
Definition: util.c:34
BOOLEAN NTAPI SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer, IN ULONG SourceBufferLength, OUT PCHAR DestinationBuffer, IN ULONG DestinationBufferSize, OUT PULONG UTF8Count, OUT PULONG ProcessedCount)
Definition: util.c:91
PSAC_MESSAGE_ENTRY GlobalMessageTable
Definition: util.c:31
ULONG NTAPI GetMessageLineCount(IN ULONG MessageIndex)
Definition: util.c:1233
PVOID RequestSacCmdEventObjectBody
Definition: util.c:22
NTSTATUS InvokeUserModeService(VOID)
Definition: util.c:1269
NTSTATUS NTAPI GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission)
Definition: util.c:981
PVOID RequestSacCmdFailureEventObjectBody
Definition: util.c:26
VOID NTAPI InitializeMachineInformation(VOID)
Definition: util.c:692
VOID NTAPI InitializeCmdEventInfo(VOID)
Definition: util.c:1062
PCHAR Utf8ConversionBuffer
Definition: util.c:17
NTSTATUS NTAPI GetRegistryValueBuffer(IN PCWSTR KeyName, IN PWCHAR ValueName, IN PKEY_VALUE_PARTIAL_INFORMATION *Buffer)
Definition: util.c:392
PKEVENT RequestSacCmdSuccessEventWaitObjectBody
Definition: util.c:25
NTSTATUS RegisterSacCmdEvent(IN PVOID Object, IN PKEVENT SetupCmdEvent[])
Definition: util.c:1295
NTSTATUS NTAPI SetRegistryValue(IN PCWSTR KeyName, IN PWCHAR ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: util.c:465
BOOLEAN HaveUserModeServiceCmdEventInfo
Definition: util.c:29
ULONG ConvertAnsiToUnicode(IN PWCHAR pwch, IN PCHAR pch, IN ULONG length)
Definition: util.c:1251
NTSTATUS NTAPI SerialBufferGetChar(OUT PCHAR Char)
Definition: util.c:1212
PKEVENT RequestSacCmdEventWaitObjectBody
Definition: util.c:23
NTSTATUS NTAPI TearDownGlobalMessageTable(VOID)
Definition: util.c:379
NTSTATUS NTAPI TranslateMachineInformationXML(IN PWCHAR *Buffer, IN PWCHAR ExtraData)
Definition: util.c:541
NTSTATUS UnregisterSacCmdEvent(IN PFILE_OBJECT FileObject)
Definition: util.c:1304
#define ULONG_PTR
Definition: config.h:101
int Fail
Definition: ehthrow.cxx:24
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG BuildNumber
Definition: ros_glue.cpp:6
ULONG MajorVersion
Definition: ros_glue.cpp:4
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ HeadlessCmdPutData
Definition: hdl.h:150
@ HeadlessCmdQueryGUID
Definition: hdl.h:149
@ HeadlessCmdSetBlueScreenData
Definition: hdl.h:147
NTSTATUS NTAPI HeadlessDispatch(IN HEADLESS_CMD Command, IN PVOID InputBuffer, IN SIZE_T InputBufferSize, OUT PVOID OutputBuffer, OUT PSIZE_T OutputBufferSize)
Definition: hdlsterm.c:570
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define pch(ap)
Definition: match.c:418
#define ASSERT(a)
Definition: mode.c:44
static PWSTR GuidString
Definition: apphelp.c:93
ObjectType
Definition: metafile.c:81
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1909
NTSYSAPI NTSTATUS NTAPI RtlFindMessage(_In_ PVOID BaseAddress, _In_ ULONG Type, _In_ ULONG Language, _In_ ULONG MessageId, _Out_ PMESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
#define MESSAGE_RESOURCE_UNICODE
Definition: rtltypes.h:351
DWORD Interval
Definition: netstat.c:30
#define SYNCHRONIZE
Definition: nt_native.h:61
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_WRITE
Definition: nt_native.h:1031
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN NTAPI ExVerifySuite(SUITE_TYPE SuiteType)
Definition: sysinfo.c:377
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
long LONG
Definition: pedump.c:60
#define SAC_DBG(x,...)
Definition: sacdrv.h:37
#define CHECK_PARAMETER2(x)
Definition: sacdrv.h:58
#define SacAllocatePool(Length, Tag)
Definition: sacdrv.h:24
#define SAC_DBG_MACHINE
Definition: sacdrv.h:36
#define CHECK_PARAMETER1(x)
Definition: sacdrv.h:56
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status)
Definition: sacdrv.h:47
#define CHECK_PARAMETER4(x)
Definition: sacdrv.h:62
#define SAC_MAX_MESSAGES
Definition: sacdrv.h:156
#define SAC_DBG_ENTRY_EXIT
Definition: sacdrv.h:32
#define SAC_SERIAL_PORT_BUFFER_SIZE
Definition: sacdrv.h:155
#define SAC_DBG_INIT
Definition: sacdrv.h:34
#define GLOBAL_BLOCK_TAG
Definition: sacdrv.h:142
struct _SAC_MESSAGE_ENTRY SAC_MESSAGE_ENTRY
#define SacFreePool(Pointer)
Definition: sacdrv.h:26
#define SAC_DBG_UTIL
Definition: sacdrv.h:33
#define REG_DWORD
Definition: sdbapi.c:596
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define LANG_NEUTRAL
Definition: nls.h:22
_In_ DWORD _Out_ PDWORD _In_opt_ PCSTR MachineName
Definition: setupapi.h:1293
#define STATUS_SUCCESS
Definition: shellext.h:65
static void Exit(void)
Definition: sock.c:1330
UCHAR Data[ANYSIZE_ARRAY]
Definition: hdl.h:78
Definition: rtltypes.h:1896
UCHAR Text[ANYSIZE_ARRAY]
Definition: rtltypes.h:1899
USHORT Flags
Definition: rtltypes.h:1898
USHORT Length
Definition: rtltypes.h:1897
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
USHORT wServicePackMinor
Definition: rtltypes.h:276
ULONG dwBuildNumber
Definition: rtltypes.h:272
USHORT wServicePackMajor
Definition: rtltypes.h:275
PWCHAR ProductType
Definition: sacdrv.h:499
PWCHAR MajorVersion
Definition: sacdrv.h:497
PWCHAR BuildNumber
Definition: sacdrv.h:498
PWCHAR MachineGuid
Definition: sacdrv.h:495
PWCHAR ProcessorArchitecture
Definition: sacdrv.h:496
PWCHAR ServicePack
Definition: sacdrv.h:500
PWCHAR MachineName
Definition: sacdrv.h:494
Definition: sacdrv.h:206
ULONG Index
Definition: sacdrv.h:207
PWCHAR Buffer
Definition: sacdrv.h:208
_In_ ULONG _In_ ULONG _In_ ULONG DestinationBufferSize
Definition: tdikrnl.h:1007
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
#define GetMessage
Definition: winuser.h:5790
@ DataCenter
Definition: extypes.h:27
@ Enterprise
Definition: extypes.h:21
@ EmbeddedNT
Definition: extypes.h:26
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175