ReactOS  0.4.15-dev-4614-ga5a6101
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 
39 BOOLEAN
40 NTAPI
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 */
85  ASSERT(FALSE);
86  return FALSE;
87 }
88 
89 BOOLEAN
90 NTAPI
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 
137 PWCHAR
138 NTAPI
139 GetMessage(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 
163 NTSTATUS
164 NTAPI
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 
200 VOID
201 NTAPI
202 SacFormatMessage(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 
278 NTSTATUS
279 NTAPI
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,
300  LANG_NEUTRAL,
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 */
329  if (!GlobalMessageTable)
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,
345  LANG_NEUTRAL,
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 
371 Exit:
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 
377 NTSTATUS
378 NTAPI
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 
390 NTSTATUS
391 NTAPI
395 {
399  HANDLE Handle;
400  ULONG ResultLength = 0;
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,
447  ResultLength,
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 
456 Quit:
457  /* Close the handle and exit */
458  ZwClose(Handle);
459  SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Exiting.\n");
460  return Status;
461 }
462 
463 NTSTATUS
464 NTAPI
467  IN ULONG Type,
468  IN PVOID Data,
469  IN ULONG DataSize)
470 {
474  HANDLE Handle;
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 */
507  ZwClose(Handle);
508  SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n");
509  return Status;
510 }
511 
512 NTSTATUS
513 NTAPI
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 
539 NTSTATUS
540 NTAPI
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 
690 VOID
691 NTAPI
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;
701  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
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 */
706  if (MachineInformation)
707  {
708  SAC_DBG(SAC_DBG_MACHINE, "SAC Initialize Machine Information:: MachineInformationBuffer already initialized.\n");
709  return;
710  }
711 
712  /* Allocate the machine information */
715  if (!MachineInformation)
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 */
778  MachineName,
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 
970 Fail:
971  /* In the failure path, always cleanup the machine information buffer */
972  if (MachineInformation)
973  {
975  }
976  SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n");
977 }
978 
979 NTSTATUS
980 NTAPI
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 
1006 NTSTATUS
1007 NTAPI
1009 {
1010  NTSTATUS Status;
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 
1060 VOID
1061 NTAPI
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 
1102 NTSTATUS
1103 NTAPI
1105 {
1106  PWCHAR XmlBuffer;
1108  SIZE_T Length, HeaderLength, TotalLength;
1109  NTSTATUS Status;
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,
1141  TotalLength,
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 
1154 VOID
1155 NTAPI
1157 {
1159 
1160  /* Free every cached string of machine information */
1168 }
1169 
1170 BOOLEAN
1171 NTAPI
1173  OUT PVOID *WaitObject,
1174  OUT PVOID *ActualWaitObject)
1175 {
1176  PVOID Object;
1177  NTSTATUS Status;
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 
1210 NTSTATUS
1211 NTAPI
1213 {
1214  /* Check if nothing's been produced yet */
1216  {
1217  return STATUS_NO_DATA_DETECTED;
1218  }
1219 
1220  /* Consume the produced character and clear it*/
1223 
1224  /* Advance the index and return success */
1226  (SerialPortConsumerIndex + 1) &
1228  return STATUS_SUCCESS;
1229 }
1230 
1231 ULONG
1232 NTAPI
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 
1250 ULONG
1252  IN PWCHAR pwch,
1253  IN PCHAR pch,
1254  IN ULONG length
1255  )
1256 {
1257  return STATUS_NOT_IMPLEMENTED;
1258 }
1259 
1260 BOOLEAN
1263  )
1264 {
1265  return FALSE;
1266 }
1267 
1268 NTSTATUS
1270  VOID
1271  )
1272 {
1273  return STATUS_NOT_IMPLEMENTED;
1274 }
1275 
1276 NTSTATUS
1278  IN PWCHAR Buffer)
1279 {
1280  return STATUS_NOT_IMPLEMENTED;
1281 }
1282 
1283 NTSTATUS
1285  IN PWCHAR SourceStr,
1286  IN ULONG Interval,
1287  IN PWCHAR InsertStr,
1288  OUT PWCHAR pDestStr
1289  )
1290 {
1291  return STATUS_NOT_IMPLEMENTED;
1292 }
1293 
1294 NTSTATUS
1296  IN PVOID Object,
1297  IN PKEVENT SetupCmdEvent[]
1298  )
1299 {
1300  return STATUS_NOT_IMPLEMENTED;
1301 }
1302 
1303 NTSTATUS
1306  )
1307 {
1308  return STATUS_NOT_IMPLEMENTED;
1309 }
struct _SAC_MESSAGE_ENTRY SAC_MESSAGE_ENTRY
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
PKEVENT RequestSacCmdFailureEventWaitObjectBody
Definition: util.c:27
ObjectType
Definition: metafile.c:80
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
#define MESSAGE_RESOURCE_UNICODE
Definition: rtltypes.h:351
static PWSTR GuidString
Definition: apphelp.c:93
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
PVOID RequestSacCmdSuccessEventObjectBody
Definition: util.c:24
Definition: rtltypes.h:1895
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG MajorVersion
Definition: ros_glue.cpp:4
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
NTSTATUS NTAPI TranslateMachineInformationXML(IN PWCHAR *Buffer, IN PWCHAR ExtraData)
Definition: util.c:541
NTSTATUS UnregisterSacCmdEvent(IN PFILE_OBJECT FileObject)
Definition: util.c:1304
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: sacdrv.h:205
NTSTATUS NTAPI UTF8EncodeAndSend(IN PWCHAR String)
Definition: util.c:165
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define LANG_NEUTRAL
Definition: nls.h:22
PWCHAR BuildNumber
Definition: sacdrv.h:498
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
char CHAR
Definition: xmlstorage.h:175
ULONG NTAPI GetMessageLineCount(IN ULONG MessageIndex)
Definition: util.c:1233
NTSTATUS TranslateMachineInformationText(IN PWCHAR Buffer)
Definition: util.c:1277
LONG NTSTATUS
Definition: precomp.h:26
PSAC_MESSAGE_ENTRY GlobalMessageTable
Definition: util.c:31
ULONG GlobalMessageTableCount
Definition: util.c:32
NTSYSAPI NTSTATUS NTAPI RtlFindMessage(_In_ PVOID BaseAddress, _In_ ULONG Type, _In_ ULONG Language, _In_ ULONG MessageId, _Out_ PMESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
_In_ DWORD _Out_ PDWORD _In_opt_ PCSTR MachineName
Definition: setupapi.h:1291
PWCHAR ServicePack
Definition: sacdrv.h:500
VOID NTAPI InitializeCmdEventInfo(VOID)
Definition: util.c:1062
PWCHAR Buffer
Definition: sacdrv.h:208
uint16_t * PWCHAR
Definition: typedefs.h:56
_In_ ULONG TotalLength
Definition: usbdlib.h:158
BOOLEAN NTAPI ExVerifySuite(SUITE_TYPE SuiteType)
Definition: sysinfo.c:377
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
USHORT Flags
Definition: rtltypes.h:1898
#define pch(ap)
Definition: match.c:418
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
#define GLOBAL_BLOCK_TAG
Definition: sacdrv.h:142
PWCHAR ProcessorArchitecture
Definition: sacdrv.h:496
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
NTSTATUS NTAPI RegisterBlueScreenMachineInformation(VOID)
Definition: util.c:1104
return STATUS_NOT_IMPLEMENTED
PWCHAR MachineName
Definition: sacdrv.h:494
static ULONG
Definition: util.c:35
#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
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ANSI_NULL
long LONG
Definition: pedump.c:60
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned char BOOLEAN
PWCHAR MajorVersion
Definition: sacdrv.h:497
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1868
NTSTATUS RegisterSacCmdEvent(IN PVOID Object, IN PKEVENT SetupCmdEvent[])
Definition: util.c:1295
Definition: bufpool.h:45
#define SacAllocatePool(Length, Tag)
Definition: sacdrv.h:24
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
LONG SerialPortProducerIndex
Definition: util.c:34
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
NTSTATUS InvokeUserModeService(VOID)
Definition: util.c:1269
PCHAR Utf8ConversionBuffer
Definition: util.c:17
DWORD Interval
Definition: netstat.c:33
Status
Definition: gdiplustypes.h:24
#define KEY_WRITE
Definition: nt_native.h:1031
PFILE_OBJECT ServiceProcessFileObject
Definition: util.c:28
UCHAR Text[ANYSIZE_ARRAY]
Definition: rtltypes.h:1899
ULONG dwMajorVersion
Definition: rtltypes.h:247
NTSTATUS NTAPI PreloadGlobalMessageTable(IN PVOID ImageBase)
Definition: util.c:280
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission)
Definition: util.c:981
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI ImposeSacCmdServiceStartTypePolicy(VOID)
Definition: util.c:1008
BOOLEAN HaveUserModeServiceCmdEventInfo
Definition: util.c:29
ULONG Utf8ConversionBufferSize
Definition: util.c:18
NTSTATUS NTAPI SerialBufferGetChar(OUT PCHAR Char)
Definition: util.c:1212
static void Exit(void)
Definition: sock.c:1331
NTSTATUS NTAPI CopyRegistryValueData(IN PVOID *Buffer, IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo)
Definition: util.c:514
PSAC_MACHINE_INFO MachineInformation
Definition: util.c:20
#define ObDereferenceObject
Definition: obfuncs.h:203
Type
Definition: Type.h:6
#define SacFreePool(Pointer)
Definition: sacdrv.h:26
#define SAC_DBG_MACHINE
Definition: sacdrv.h:36
#define CHECK_PARAMETER1(x)
Definition: sacdrv.h:56
PKEVENT RequestSacCmdSuccessEventWaitObjectBody
Definition: util.c:25
LONG SerialPortConsumerIndex
Definition: util.c:34
* PFILE_OBJECT
Definition: iotypes.h:1998
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PKEVENT RequestSacCmdEventWaitObjectBody
Definition: util.c:23
ULONG dwBuildNumber
Definition: rtltypes.h:249
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
char * PBOOLEAN
Definition: retypes.h:11
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define SAC_DBG_INIT
Definition: sacdrv.h:34
#define SAC_DBG(x,...)
Definition: sacdrv.h:37
NTSTATUS NTAPI GetRegistryValueBuffer(IN PCWSTR KeyName, IN PWCHAR ValueName, IN PKEY_VALUE_PARTIAL_INFORMATION *Buffer)
Definition: util.c:392
PWCHAR NTAPI GetMessage(IN ULONG MessageIndex)
Definition: util.c:139
#define PAGE_SIZE
Definition: env_spec_w32.h:49
USHORT Length
Definition: rtltypes.h:1897
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131
#define SYNCHRONIZE
Definition: nt_native.h:61
int _cdecl swprintf(const WCHAR *,...)
PWCHAR MachineGuid
Definition: sacdrv.h:495
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
ULONG Index
Definition: sacdrv.h:207
ULONG BuildNumber
Definition: ros_glue.cpp:6
PCHAR SerialPortBuffer
Definition: util.c:35
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CHECK_PARAMETER4(x)
Definition: sacdrv.h:62
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
BOOLEAN IsCmdEventRegistrationProcess(IN PFILE_OBJECT FileObject)
Definition: util.c:1261
_In_ ULONG _In_ ULONG _In_ ULONG DestinationBufferSize
Definition: tdikrnl.h:1006
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
VOID NTAPI FreeMachineInformation(VOID)
Definition: util.c:1156
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status)
Definition: sacdrv.h:47
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
PVOID RequestSacCmdEventObjectBody
Definition: util.c:22
BOOLEAN NTAPI SacTranslateUtf8ToUnicode(IN CHAR Utf8Char, IN PCHAR Utf8Buffer, OUT PWCHAR Utf8Value)
Definition: util.c:41
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG ConvertAnsiToUnicode(IN PWCHAR pwch, IN PCHAR pch, IN ULONG length)
Definition: util.c:1251
#define CHECK_PARAMETER2(x)
Definition: sacdrv.h:58
NTSTATUS NTAPI SetRegistryValue(IN PCWSTR KeyName, IN PWCHAR ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: util.c:465
#define SAC_SERIAL_PORT_BUFFER_SIZE
Definition: sacdrv.h:155
ULONG dwMinorVersion
Definition: rtltypes.h:248
VOID NTAPI SacFormatMessage(IN PWCHAR FormattedString, IN PWCHAR MessageString, IN ULONG MessageSize)
Definition: util.c:202
PWCHAR ProductType
Definition: sacdrv.h:499
_In_ HANDLE Handle
Definition: extypes.h:390
#define OUT
Definition: typedefs.h:40
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
NTSTATUS NTAPI TearDownGlobalMessageTable(VOID)
Definition: util.c:379
NTSTATUS CopyAndInsertStringAtInterval(IN PWCHAR SourceStr, IN ULONG Interval, IN PWCHAR InsertStr, OUT PWCHAR pDestStr)
Definition: util.c:1284
PVOID RequestSacCmdFailureEventObjectBody
Definition: util.c:26
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define SAC_DBG_ENTRY_EXIT
Definition: sacdrv.h:32
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
BOOLEAN NTAPI VerifyEventWaitable(IN HANDLE Handle, OUT PVOID *WaitObject, OUT PVOID *ActualWaitObject)
Definition: util.c:1172
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI InitializeMachineInformation(VOID)
Definition: util.c:692
#define SAC_DBG_UTIL
Definition: sacdrv.h:33
GLfloat GLfloat p
Definition: glext.h:8902
#define REG_DWORD
Definition: sdbapi.c:596
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
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
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
char * Text
Definition: combotst.c:136
#define PAGED_CODE()
#define SAC_MAX_MESSAGES
Definition: sacdrv.h:156