Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregistry.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2003 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS text-mode setup 00022 * FILE: subsys/system/usetup/registry.c 00023 * PURPOSE: Registry creation functions 00024 * PROGRAMMER: Eric Kohl 00025 */ 00026 00027 /* INCLUDES *****************************************************************/ 00028 00029 #include "usetup.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 #ifdef __REACTOS__ 00035 #define FLG_ADDREG_BINVALUETYPE 0x00000001 00036 #define FLG_ADDREG_NOCLOBBER 0x00000002 00037 #define FLG_ADDREG_DELVAL 0x00000004 00038 #define FLG_ADDREG_APPEND 0x00000008 00039 #define FLG_ADDREG_KEYONLY 0x00000010 00040 #define FLG_ADDREG_OVERWRITEONLY 0x00000020 00041 #define FLG_ADDREG_TYPE_SZ 0x00000000 00042 #define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000 00043 #define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000 00044 #define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE) 00045 #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) 00046 #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) 00047 #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) 00048 #endif 00049 00050 #include <pshpack1.h> 00051 00052 typedef struct _REG_DISK_MOUNT_INFO 00053 { 00054 ULONG Signature; 00055 LARGE_INTEGER StartingOffset; 00056 } REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO; 00057 00058 #include <poppack.h> 00059 00060 /* FUNCTIONS ****************************************************************/ 00061 00062 static BOOLEAN 00063 GetRootKey (PWCHAR Name) 00064 { 00065 if (!_wcsicmp (Name, L"HKCR")) 00066 { 00067 wcscpy (Name, L"\\Registry\\Machine\\SOFTWARE\\Classes\\"); 00068 return TRUE; 00069 } 00070 00071 if (!_wcsicmp (Name, L"HKCU")) 00072 { 00073 wcscpy (Name, L"\\Registry\\User\\.DEFAULT\\"); 00074 return TRUE; 00075 } 00076 00077 if (!_wcsicmp (Name, L"HKLM")) 00078 { 00079 wcscpy (Name, L"\\Registry\\Machine\\"); 00080 return TRUE; 00081 } 00082 00083 if (!_wcsicmp (Name, L"HKU")) 00084 { 00085 wcscpy (Name, L"\\Registry\\User\\"); 00086 return TRUE; 00087 } 00088 00089 #if 0 00090 if (!_wcsicmp (Name, L"HKR")) 00091 return FALSE; 00092 #endif 00093 00094 return FALSE; 00095 } 00096 00097 00098 /*********************************************************************** 00099 * append_multi_sz_value 00100 * 00101 * Append a multisz string to a multisz registry value. 00102 */ 00103 #if 0 00104 static void 00105 append_multi_sz_value (HANDLE hkey, 00106 const WCHAR *value, 00107 const WCHAR *strings, 00108 DWORD str_size ) 00109 { 00110 DWORD size, type, total; 00111 WCHAR *buffer, *p; 00112 00113 if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; 00114 if (type != REG_MULTI_SZ) return; 00115 00116 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return; 00117 if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; 00118 00119 /* compare each string against all the existing ones */ 00120 total = size; 00121 while (*strings) 00122 { 00123 int len = strlenW(strings) + 1; 00124 00125 for (p = buffer; *p; p += strlenW(p) + 1) 00126 if (!strcmpiW( p, strings )) break; 00127 00128 if (!*p) /* not found, need to append it */ 00129 { 00130 memcpy( p, strings, len * sizeof(WCHAR) ); 00131 p[len] = 0; 00132 total += len; 00133 } 00134 strings += len; 00135 } 00136 if (total != size) 00137 { 00138 TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) ); 00139 RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total ); 00140 } 00141 done: 00142 HeapFree( GetProcessHeap(), 0, buffer ); 00143 } 00144 #endif 00145 00146 /*********************************************************************** 00147 * delete_multi_sz_value 00148 * 00149 * Remove a string from a multisz registry value. 00150 */ 00151 #if 0 00152 static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string ) 00153 { 00154 DWORD size, type; 00155 WCHAR *buffer, *src, *dst; 00156 00157 if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; 00158 if (type != REG_MULTI_SZ) return; 00159 /* allocate double the size, one for value before and one for after */ 00160 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return; 00161 if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; 00162 src = buffer; 00163 dst = buffer + size; 00164 while (*src) 00165 { 00166 int len = strlenW(src) + 1; 00167 if (strcmpiW( src, string )) 00168 { 00169 memcpy( dst, src, len * sizeof(WCHAR) ); 00170 dst += len; 00171 } 00172 src += len; 00173 } 00174 *dst++ = 0; 00175 if (dst != buffer + 2*size) /* did we remove something? */ 00176 { 00177 TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) ); 00178 RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, 00179 (BYTE *)(buffer + size), dst - (buffer + size) ); 00180 } 00181 done: 00182 HeapFree( GetProcessHeap(), 0, buffer ); 00183 } 00184 #endif 00185 00186 /*********************************************************************** 00187 * do_reg_operation 00188 * 00189 * Perform an add/delete registry operation depending on the flags. 00190 */ 00191 static BOOLEAN 00192 do_reg_operation(HANDLE KeyHandle, 00193 PUNICODE_STRING ValueName, 00194 PINFCONTEXT Context, 00195 ULONG Flags) 00196 { 00197 WCHAR EmptyStr = (WCHAR)0; 00198 ULONG Type; 00199 ULONG Size; 00200 00201 if (Flags & FLG_ADDREG_DELVAL) /* deletion */ 00202 { 00203 #if 0 00204 if (ValueName) 00205 { 00206 RegDeleteValueW( KeyHandle, ValueName ); 00207 } 00208 else 00209 { 00210 RegDeleteKeyW( KeyHandle, NULL ); 00211 } 00212 #endif 00213 return TRUE; 00214 } 00215 00216 if (Flags & FLG_ADDREG_KEYONLY) 00217 return TRUE; 00218 00219 #if 0 00220 if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) 00221 { 00222 BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL ); 00223 if (exists && (flags & FLG_ADDREG_NOCLOBBER)) 00224 return TRUE; 00225 if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) 00226 return TRUE; 00227 } 00228 #endif 00229 00230 switch (Flags & FLG_ADDREG_TYPE_MASK) 00231 { 00232 case FLG_ADDREG_TYPE_SZ: 00233 Type = REG_SZ; 00234 break; 00235 00236 case FLG_ADDREG_TYPE_MULTI_SZ: 00237 Type = REG_MULTI_SZ; 00238 break; 00239 00240 case FLG_ADDREG_TYPE_EXPAND_SZ: 00241 Type = REG_EXPAND_SZ; 00242 break; 00243 00244 case FLG_ADDREG_TYPE_BINARY: 00245 Type = REG_BINARY; 00246 break; 00247 00248 case FLG_ADDREG_TYPE_DWORD: 00249 Type = REG_DWORD; 00250 break; 00251 00252 case FLG_ADDREG_TYPE_NONE: 00253 Type = REG_NONE; 00254 break; 00255 00256 default: 00257 Type = Flags >> 16; 00258 break; 00259 } 00260 00261 if (!(Flags & FLG_ADDREG_BINVALUETYPE) || 00262 (Type == REG_DWORD && SetupGetFieldCount (Context) == 5)) 00263 { 00264 PWCHAR Str = NULL; 00265 00266 if (Type == REG_MULTI_SZ) 00267 { 00268 if (!SetupGetMultiSzFieldW (Context, 5, NULL, 0, &Size)) 00269 Size = 0; 00270 00271 if (Size) 00272 { 00273 Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); 00274 if (Str == NULL) 00275 return FALSE; 00276 00277 SetupGetMultiSzFieldW (Context, 5, Str, Size, NULL); 00278 } 00279 00280 if (Flags & FLG_ADDREG_APPEND) 00281 { 00282 if (Str == NULL) 00283 return TRUE; 00284 00285 // append_multi_sz_value( hkey, value, str, size ); 00286 00287 RtlFreeHeap (ProcessHeap, 0, Str); 00288 return TRUE; 00289 } 00290 /* else fall through to normal string handling */ 00291 } 00292 else 00293 { 00294 if (!SetupGetStringFieldW (Context, 5, NULL, 0, &Size)) 00295 Size = 0; 00296 00297 if (Size) 00298 { 00299 Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); 00300 if (Str == NULL) 00301 return FALSE; 00302 00303 SetupGetStringFieldW (Context, 5, Str, Size, NULL); 00304 } 00305 } 00306 00307 if (Type == REG_DWORD) 00308 { 00309 ULONG dw = Str ? wcstoul (Str, NULL, 0) : 0; 00310 00311 DPRINT("setting dword %wZ to %lx\n", ValueName, dw); 00312 00313 #ifdef __REACTOS__ 00314 NtSetValueKey (KeyHandle, 00315 ValueName, 00316 0, 00317 Type, 00318 (PVOID)&dw, 00319 sizeof(ULONG)); 00320 #else 00321 RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&dw, sizeof(ULONG)); 00322 #endif 00323 } 00324 else 00325 { 00326 DPRINT("setting value %wZ to %S\n", ValueName, Str); 00327 00328 if (Str) 00329 { 00330 #ifdef __REACTOS__ 00331 NtSetValueKey (KeyHandle, 00332 ValueName, 00333 0, 00334 Type, 00335 (PVOID)Str, 00336 Size * sizeof(WCHAR)); 00337 #else 00338 RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Str, Size * sizeof(WCHAR)); 00339 #endif 00340 } 00341 else 00342 { 00343 #ifdef __REACTOS__ 00344 NtSetValueKey (KeyHandle, 00345 ValueName, 00346 0, 00347 Type, 00348 (PVOID)&EmptyStr, 00349 sizeof(WCHAR)); 00350 #else 00351 RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&EmptyStr, sizeof(WCHAR)); 00352 #endif 00353 } 00354 } 00355 RtlFreeHeap (ProcessHeap, 0, Str); 00356 } 00357 else /* get the binary data */ 00358 { 00359 PUCHAR Data = NULL; 00360 00361 if (!SetupGetBinaryField (Context, 5, NULL, 0, &Size)) 00362 Size = 0; 00363 00364 if (Size) 00365 { 00366 Data = (unsigned char*) RtlAllocateHeap (ProcessHeap, 0, Size); 00367 if (Data == NULL) 00368 return FALSE; 00369 00370 DPRINT("setting binary data %wZ len %lu\n", ValueName, Size); 00371 SetupGetBinaryField (Context, 5, Data, Size, NULL); 00372 } 00373 00374 #ifdef __REACTOS__ 00375 NtSetValueKey (KeyHandle, 00376 ValueName, 00377 0, 00378 Type, 00379 (PVOID)Data, 00380 Size); 00381 #else 00382 RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Data, Size); 00383 #endif 00384 00385 RtlFreeHeap (ProcessHeap, 0, Data); 00386 } 00387 00388 return TRUE; 00389 } 00390 00391 #ifdef __REACTOS__ 00392 NTSTATUS 00393 CreateNestedKey (PHANDLE KeyHandle, 00394 ACCESS_MASK DesiredAccess, 00395 POBJECT_ATTRIBUTES ObjectAttributes) 00396 { 00397 OBJECT_ATTRIBUTES LocalObjectAttributes; 00398 UNICODE_STRING LocalKeyName; 00399 ULONG Disposition; 00400 NTSTATUS Status; 00401 USHORT FullNameLength; 00402 PWCHAR Ptr; 00403 HANDLE LocalKeyHandle; 00404 00405 Status = NtCreateKey (KeyHandle, 00406 KEY_ALL_ACCESS, 00407 ObjectAttributes, 00408 0, 00409 NULL, 00410 0, 00411 &Disposition); 00412 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); 00413 if (Status != STATUS_OBJECT_NAME_NOT_FOUND) 00414 return Status; 00415 00416 /* Copy object attributes */ 00417 RtlCopyMemory (&LocalObjectAttributes, 00418 ObjectAttributes, 00419 sizeof(OBJECT_ATTRIBUTES)); 00420 RtlCreateUnicodeString (&LocalKeyName, 00421 ObjectAttributes->ObjectName->Buffer); 00422 LocalObjectAttributes.ObjectName = &LocalKeyName; 00423 FullNameLength = LocalKeyName.Length; 00424 00425 /* Remove the last part of the key name and try to create the key again. */ 00426 while (Status == STATUS_OBJECT_NAME_NOT_FOUND) 00427 { 00428 Ptr = wcsrchr (LocalKeyName.Buffer, '\\'); 00429 if (Ptr == NULL || Ptr == LocalKeyName.Buffer) 00430 { 00431 Status = STATUS_UNSUCCESSFUL; 00432 break; 00433 } 00434 *Ptr = (WCHAR)0; 00435 LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR); 00436 00437 Status = NtCreateKey (&LocalKeyHandle, 00438 KEY_ALL_ACCESS, 00439 &LocalObjectAttributes, 00440 0, 00441 NULL, 00442 0, 00443 &Disposition); 00444 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); 00445 } 00446 00447 if (!NT_SUCCESS(Status)) 00448 { 00449 RtlFreeUnicodeString (&LocalKeyName); 00450 return Status; 00451 } 00452 00453 /* Add removed parts of the key name and create them too. */ 00454 while (TRUE) 00455 { 00456 if (LocalKeyName.Length == FullNameLength) 00457 { 00458 Status = STATUS_SUCCESS; 00459 *KeyHandle = LocalKeyHandle; 00460 break; 00461 } 00462 NtClose (LocalKeyHandle); 00463 00464 LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\'; 00465 LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR); 00466 00467 Status = NtCreateKey (&LocalKeyHandle, 00468 KEY_ALL_ACCESS, 00469 &LocalObjectAttributes, 00470 0, 00471 NULL, 00472 0, 00473 &Disposition); 00474 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); 00475 if (!NT_SUCCESS(Status)) 00476 break; 00477 } 00478 00479 RtlFreeUnicodeString (&LocalKeyName); 00480 00481 return Status; 00482 } 00483 #endif 00484 00485 /*********************************************************************** 00486 * registry_callback 00487 * 00488 * Called once for each AddReg and DelReg entry in a given section. 00489 */ 00490 static BOOLEAN 00491 registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete) 00492 { 00493 OBJECT_ATTRIBUTES ObjectAttributes; 00494 WCHAR Buffer[MAX_INF_STRING_LENGTH]; 00495 UNICODE_STRING Name; 00496 UNICODE_STRING Value; 00497 PUNICODE_STRING ValuePtr; 00498 NTSTATUS Status; 00499 UINT Flags; 00500 ULONG Length; 00501 00502 INFCONTEXT Context; 00503 HANDLE KeyHandle; 00504 BOOLEAN Ok; 00505 00506 00507 Ok = SetupFindFirstLineW (hInf, Section, NULL, &Context); 00508 00509 if (Ok) 00510 { 00511 for (;Ok; Ok = SetupFindNextLine (&Context, &Context)) 00512 { 00513 /* get root */ 00514 if (!SetupGetStringFieldW (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL)) 00515 continue; 00516 if (!GetRootKey (Buffer)) 00517 continue; 00518 00519 /* get key */ 00520 Length = wcslen (Buffer); 00521 if (!SetupGetStringFieldW (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL)) 00522 *Buffer = 0; 00523 00524 DPRINT("KeyName: <%S>\n", Buffer); 00525 00526 /* get flags */ 00527 if (!SetupGetIntField (&Context, 4, (PINT)&Flags)) 00528 Flags = 0; 00529 00530 DPRINT("Flags: %lx\n", Flags); 00531 00532 #ifdef __REACTOS__ 00533 RtlInitUnicodeString (&Name, 00534 Buffer); 00535 00536 InitializeObjectAttributes (&ObjectAttributes, 00537 &Name, 00538 OBJ_CASE_INSENSITIVE, 00539 NULL, 00540 NULL); 00541 00542 if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) 00543 { 00544 Status = NtOpenKey (&KeyHandle, 00545 KEY_ALL_ACCESS, 00546 &ObjectAttributes); 00547 if (!NT_SUCCESS(Status)) 00548 { 00549 DPRINT("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status); 00550 continue; /* ignore if it doesn't exist */ 00551 } 00552 } 00553 else 00554 { 00555 Status = CreateNestedKey (&KeyHandle, 00556 KEY_ALL_ACCESS, 00557 &ObjectAttributes); 00558 if (!NT_SUCCESS(Status)) 00559 { 00560 DPRINT("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status); 00561 continue; 00562 } 00563 } 00564 #else 00565 if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) 00566 { 00567 LONG rc = RegOpenKeyW(NULL, Buffer, &KeyHandle); 00568 if (rc != ERROR_SUCCESS) 00569 { 00570 DPRINT("RegOpenKeyW(%S) failed (error %lu)\n", Buffer, rc); 00571 continue; /* ignore if it doesn't exist */ 00572 } 00573 } 00574 else 00575 { 00576 LONG rc = RegCreateKeyW(NULL, Buffer, &KeyHandle); 00577 if (rc != ERROR_SUCCESS) 00578 { 00579 DPRINT("RegCreateKeyW(%S) failed (error %lu)\n", Buffer, rc); 00580 continue; 00581 } 00582 } 00583 #endif 00584 00585 /* get value name */ 00586 if (SetupGetStringFieldW (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL)) 00587 { 00588 RtlInitUnicodeString (&Value, 00589 Buffer); 00590 ValuePtr = &Value; 00591 } 00592 else 00593 { 00594 ValuePtr = NULL; 00595 } 00596 00597 /* and now do it */ 00598 if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags)) 00599 { 00600 NtClose (KeyHandle); 00601 return FALSE; 00602 } 00603 00604 #ifdef __REACTOS__ 00605 NtClose (KeyHandle); 00606 #endif 00607 } 00608 } 00609 00610 return TRUE; 00611 } 00612 00613 00614 BOOLEAN 00615 ImportRegistryFile(PWSTR Filename, 00616 PWSTR Section, 00617 LCID LocaleId, 00618 BOOLEAN Delete) 00619 { 00620 WCHAR FileNameBuffer[MAX_PATH]; 00621 HINF hInf; 00622 UINT ErrorLine; 00623 00624 /* Load inf file from install media. */ 00625 wcscpy(FileNameBuffer, SourcePath.Buffer); 00626 wcscat(FileNameBuffer, L"\\"); 00627 wcscat(FileNameBuffer, Filename); 00628 00629 hInf = SetupOpenInfFileW( 00630 FileNameBuffer, 00631 NULL, 00632 INF_STYLE_WIN4, 00633 LocaleId, 00634 &ErrorLine); 00635 if (hInf == INVALID_HANDLE_VALUE) 00636 { 00637 DPRINT1("SetupOpenInfFile() failed\n"); 00638 return FALSE; 00639 } 00640 00641 if (!registry_callback (hInf, L"AddReg", FALSE)) 00642 { 00643 DPRINT1("registry_callback() failed\n"); 00644 } 00645 00646 InfCloseFile (hInf); 00647 00648 return TRUE; 00649 } 00650 00651 00652 BOOLEAN 00653 SetInstallPathValue(PUNICODE_STRING InstallPath) 00654 { 00655 OBJECT_ATTRIBUTES ObjectAttributes; 00656 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE"); 00657 UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath"); 00658 HANDLE KeyHandle; 00659 NTSTATUS Status; 00660 00661 /* Create the 'secret' InstallPath key */ 00662 InitializeObjectAttributes (&ObjectAttributes, 00663 &KeyName, 00664 OBJ_CASE_INSENSITIVE, 00665 NULL, 00666 NULL); 00667 Status = NtOpenKey (&KeyHandle, 00668 KEY_ALL_ACCESS, 00669 &ObjectAttributes); 00670 if (!NT_SUCCESS(Status)) 00671 { 00672 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); 00673 return FALSE; 00674 } 00675 00676 Status = NtSetValueKey (KeyHandle, 00677 &ValueName, 00678 0, 00679 REG_SZ, 00680 (PVOID)InstallPath->Buffer, 00681 InstallPath->Length + sizeof(WCHAR)); 00682 NtClose(KeyHandle); 00683 if (!NT_SUCCESS(Status)) 00684 { 00685 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00686 return FALSE; 00687 } 00688 00689 return TRUE; 00690 } 00691 00692 BOOLEAN 00693 SetMountedDeviceValue(CHAR Letter, ULONG Signature, LARGE_INTEGER StartingOffset) 00694 { 00695 OBJECT_ATTRIBUTES ObjectAttributes; 00696 WCHAR ValueNameBuffer[16]; 00697 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices"); 00698 UNICODE_STRING ValueName; 00699 REG_DISK_MOUNT_INFO MountInfo; 00700 NTSTATUS Status; 00701 HANDLE KeyHandle; 00702 00703 swprintf(ValueNameBuffer, L"\\DosDevices\\%C:", Letter); 00704 RtlInitUnicodeString(&ValueName, ValueNameBuffer); 00705 00706 InitializeObjectAttributes (&ObjectAttributes, 00707 &KeyName, 00708 OBJ_CASE_INSENSITIVE, 00709 NULL, 00710 NULL); 00711 Status = NtOpenKey (&KeyHandle, 00712 KEY_ALL_ACCESS, 00713 &ObjectAttributes); 00714 if (!NT_SUCCESS(Status)) 00715 { 00716 Status = NtCreateKey(&KeyHandle, 00717 KEY_ALL_ACCESS, 00718 &ObjectAttributes, 00719 0, 00720 NULL, 00721 REG_OPTION_NON_VOLATILE, 00722 NULL); 00723 } 00724 00725 if (!NT_SUCCESS(Status)) 00726 { 00727 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 00728 return FALSE; 00729 } 00730 00731 MountInfo.Signature = Signature; 00732 MountInfo.StartingOffset = StartingOffset; 00733 Status = NtSetValueKey (KeyHandle, 00734 &ValueName, 00735 0, 00736 REG_BINARY, 00737 (PVOID)&MountInfo, 00738 sizeof(MountInfo)); 00739 NtClose(KeyHandle); 00740 if (!NT_SUCCESS(Status)) 00741 { 00742 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00743 return FALSE; 00744 } 00745 00746 return TRUE; 00747 } 00748 00749 /* EOF */ Generated on Sun May 27 2012 04:17:06 for ReactOS by
1.7.6.1
|