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