Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregistry.c
Go to the documentation of this file.
00001 /* 00002 * FreeLoader 00003 * 00004 * Copyright (C) 2001, 2002 Eric Kohl 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <freeldr.h> 00022 #include <debug.h> 00023 00024 DBG_DEFAULT_CHANNEL(REGISTRY); 00025 00026 static FRLDRHKEY RootKey; 00027 00028 VOID 00029 RegInitializeRegistry (VOID) 00030 { 00031 /* Create root key */ 00032 RootKey = MmHeapAlloc(sizeof(KEY)); 00033 00034 InitializeListHead(&RootKey->SubKeyList); 00035 InitializeListHead(&RootKey->ValueList); 00036 InitializeListHead(&RootKey->KeyList); 00037 00038 RootKey->SubKeyCount = 0; 00039 RootKey->ValueCount = 0; 00040 00041 RootKey->NameSize = 4; 00042 RootKey->Name = MmHeapAlloc(4); 00043 wcscpy (RootKey->Name, L"\\"); 00044 00045 RootKey->DataType = 0; 00046 RootKey->DataSize = 0; 00047 RootKey->Data = NULL; 00048 00049 /* Create 'SYSTEM' key */ 00050 RegCreateKey (RootKey, 00051 L"Registry\\Machine\\SYSTEM", 00052 NULL); 00053 } 00054 00055 00056 LONG 00057 RegInitCurrentControlSet(BOOLEAN LastKnownGood) 00058 { 00059 WCHAR ControlSetKeyName[80]; 00060 FRLDRHKEY SelectKey; 00061 FRLDRHKEY SystemKey; 00062 FRLDRHKEY ControlSetKey; 00063 FRLDRHKEY LinkKey; 00064 ULONG CurrentSet = 0; 00065 ULONG DefaultSet = 0; 00066 ULONG LastKnownGoodSet = 0; 00067 ULONG DataSize; 00068 LONG Error; 00069 00070 Error = RegOpenKey(NULL, 00071 L"\\Registry\\Machine\\SYSTEM\\Select", 00072 &SelectKey); 00073 if (Error != ERROR_SUCCESS) 00074 { 00075 ERR("RegOpenKey() failed (Error %u)\n", (int)Error); 00076 return Error; 00077 } 00078 00079 DataSize = sizeof(ULONG); 00080 Error = RegQueryValue(SelectKey, 00081 L"Default", 00082 NULL, 00083 (PUCHAR)&DefaultSet, 00084 &DataSize); 00085 if (Error != ERROR_SUCCESS) 00086 { 00087 ERR("RegQueryValue('Default') failed (Error %u)\n", (int)Error); 00088 return Error; 00089 } 00090 00091 DataSize = sizeof(ULONG); 00092 Error = RegQueryValue(SelectKey, 00093 L"LastKnownGood", 00094 NULL, 00095 (PUCHAR)&LastKnownGoodSet, 00096 &DataSize); 00097 if (Error != ERROR_SUCCESS) 00098 { 00099 ERR("RegQueryValue('Default') failed (Error %u)\n", (int)Error); 00100 return Error; 00101 } 00102 00103 CurrentSet = (LastKnownGood == TRUE) ? LastKnownGoodSet : DefaultSet; 00104 wcscpy(ControlSetKeyName, L"ControlSet"); 00105 switch(CurrentSet) 00106 { 00107 case 1: 00108 wcscat(ControlSetKeyName, L"001"); 00109 break; 00110 case 2: 00111 wcscat(ControlSetKeyName, L"002"); 00112 break; 00113 case 3: 00114 wcscat(ControlSetKeyName, L"003"); 00115 break; 00116 case 4: 00117 wcscat(ControlSetKeyName, L"004"); 00118 break; 00119 case 5: 00120 wcscat(ControlSetKeyName, L"005"); 00121 break; 00122 } 00123 00124 Error = RegOpenKey(NULL, 00125 L"\\Registry\\Machine\\SYSTEM", 00126 &SystemKey); 00127 if (Error != ERROR_SUCCESS) 00128 { 00129 ERR("RegOpenKey(SystemKey) failed (Error %lu)\n", Error); 00130 return Error; 00131 } 00132 00133 Error = RegOpenKey(SystemKey, 00134 ControlSetKeyName, 00135 &ControlSetKey); 00136 if (Error != ERROR_SUCCESS) 00137 { 00138 ERR("RegOpenKey(ControlSetKey) failed (Error %lu)\n", Error); 00139 return Error; 00140 } 00141 00142 Error = RegCreateKey(SystemKey, 00143 L"CurrentControlSet", 00144 &LinkKey); 00145 if (Error != ERROR_SUCCESS) 00146 { 00147 ERR("RegCreateKey(LinkKey) failed (Error %lu)\n", Error); 00148 return Error; 00149 } 00150 00151 Error = RegSetValue(LinkKey, 00152 NULL, 00153 REG_LINK, 00154 (PCHAR)&ControlSetKey, 00155 sizeof(PVOID)); 00156 if (Error != ERROR_SUCCESS) 00157 { 00158 ERR("RegSetValue(LinkKey) failed (Error %lu)\n", Error); 00159 return Error; 00160 } 00161 00162 return ERROR_SUCCESS; 00163 } 00164 00165 00166 LONG 00167 RegCreateKey(FRLDRHKEY ParentKey, 00168 PCWSTR KeyName, 00169 PFRLDRHKEY Key) 00170 { 00171 PLIST_ENTRY Ptr; 00172 FRLDRHKEY SearchKey = NULL; 00173 FRLDRHKEY CurrentKey; 00174 FRLDRHKEY NewKey; 00175 PWCHAR p; 00176 PCWSTR name; 00177 SIZE_T subkeyLength; 00178 SIZE_T stringLength; 00179 ULONG NameSize; 00180 int CmpResult; 00181 00182 TRACE("KeyName '%S'\n", KeyName); 00183 00184 if (*KeyName == L'\\') 00185 { 00186 KeyName++; 00187 CurrentKey = RootKey; 00188 } 00189 else if (ParentKey == NULL) 00190 { 00191 CurrentKey = RootKey; 00192 } 00193 else 00194 { 00195 CurrentKey = ParentKey; 00196 } 00197 00198 /* Check whether current key is a link */ 00199 if (CurrentKey->DataType == REG_LINK) 00200 { 00201 CurrentKey = (FRLDRHKEY)CurrentKey->Data; 00202 } 00203 00204 while (*KeyName != 0) 00205 { 00206 TRACE("KeyName '%S'\n", KeyName); 00207 00208 if (*KeyName == L'\\') 00209 KeyName++; 00210 p = wcschr(KeyName, L'\\'); 00211 if ((p != NULL) && (p != KeyName)) 00212 { 00213 subkeyLength = p - KeyName; 00214 stringLength = subkeyLength + 1; 00215 name = KeyName; 00216 } 00217 else 00218 { 00219 subkeyLength = wcslen(KeyName); 00220 stringLength = subkeyLength; 00221 name = KeyName; 00222 } 00223 NameSize = (ULONG)((subkeyLength + 1) * sizeof(WCHAR)); 00224 00225 Ptr = CurrentKey->SubKeyList.Flink; 00226 CmpResult = 1; 00227 while (Ptr != &CurrentKey->SubKeyList) 00228 { 00229 TRACE("Ptr 0x%x\n", Ptr); 00230 00231 SearchKey = CONTAINING_RECORD(Ptr, KEY, KeyList); 00232 TRACE("SearchKey 0x%x\n", SearchKey); 00233 TRACE("Searching '%S'\n", SearchKey->Name); 00234 CmpResult = _wcsnicmp(SearchKey->Name, name, subkeyLength); 00235 00236 if (CmpResult == 0 && SearchKey->NameSize == NameSize) break; 00237 else if (CmpResult == -1) break; 00238 00239 Ptr = Ptr->Flink; 00240 } 00241 00242 if (CmpResult != 0) 00243 { 00244 /* no key found -> create new subkey */ 00245 NewKey = MmHeapAlloc(sizeof(KEY)); 00246 if (NewKey == NULL) return ERROR_OUTOFMEMORY; 00247 00248 InitializeListHead(&NewKey->SubKeyList); 00249 InitializeListHead(&NewKey->ValueList); 00250 00251 NewKey->SubKeyCount = 0; 00252 NewKey->ValueCount = 0; 00253 00254 NewKey->DataType = 0; 00255 NewKey->DataSize = 0; 00256 NewKey->Data = NULL; 00257 00258 InsertTailList(Ptr, &NewKey->KeyList); 00259 CurrentKey->SubKeyCount++; 00260 00261 NewKey->NameSize = NameSize; 00262 NewKey->Name = (PWCHAR)MmHeapAlloc(NewKey->NameSize); 00263 if (NewKey->Name == NULL) return ERROR_OUTOFMEMORY; 00264 00265 memcpy(NewKey->Name, name, NewKey->NameSize - sizeof(WCHAR)); 00266 NewKey->Name[subkeyLength] = 0; 00267 00268 TRACE("NewKey 0x%x\n", NewKey); 00269 TRACE("NewKey '%S' Length %d\n", NewKey->Name, NewKey->NameSize); 00270 00271 CurrentKey = NewKey; 00272 } 00273 else 00274 { 00275 CurrentKey = SearchKey; 00276 00277 /* Check whether current key is a link */ 00278 if (CurrentKey->DataType == REG_LINK) 00279 { 00280 CurrentKey = (FRLDRHKEY)CurrentKey->Data; 00281 } 00282 } 00283 00284 KeyName = KeyName + stringLength; 00285 } 00286 00287 if (Key != NULL) *Key = CurrentKey; 00288 00289 return ERROR_SUCCESS; 00290 } 00291 00292 00293 LONG 00294 RegDeleteKey(FRLDRHKEY Key, 00295 PCWSTR Name) 00296 { 00297 00298 if (wcschr(Name, L'\\') != NULL) return ERROR_INVALID_PARAMETER; 00299 00300 return ERROR_SUCCESS; 00301 } 00302 00303 00304 LONG 00305 RegEnumKey(FRLDRHKEY Key, 00306 ULONG Index, 00307 PWCHAR Name, 00308 ULONG* NameSize) 00309 { 00310 PLIST_ENTRY Ptr; 00311 FRLDRHKEY SearchKey; 00312 ULONG Count = 0; 00313 ULONG Size; 00314 00315 Ptr = Key->SubKeyList.Flink; 00316 while (Ptr != &Key->SubKeyList) 00317 { 00318 if (Index == Count) break; 00319 00320 Count++; 00321 Ptr = Ptr->Flink; 00322 } 00323 00324 if (Ptr == &Key->SubKeyList) return ERROR_NO_MORE_ITEMS; 00325 00326 SearchKey = CONTAINING_RECORD(Ptr, KEY, KeyList); 00327 00328 TRACE("Name '%S' Length %d\n", SearchKey->Name, SearchKey->NameSize); 00329 00330 Size = min(SearchKey->NameSize, *NameSize); 00331 *NameSize = Size; 00332 memcpy(Name, SearchKey->Name, Size); 00333 00334 return ERROR_SUCCESS; 00335 } 00336 00337 00338 LONG 00339 RegOpenKey(FRLDRHKEY ParentKey, 00340 PCWSTR KeyName, 00341 PFRLDRHKEY Key) 00342 { 00343 PLIST_ENTRY Ptr; 00344 FRLDRHKEY SearchKey = NULL; 00345 FRLDRHKEY CurrentKey; 00346 PWCHAR p; 00347 PCWSTR name; 00348 SIZE_T subkeyLength; 00349 SIZE_T stringLength; 00350 ULONG NameSize; 00351 00352 TRACE("KeyName '%S'\n", KeyName); 00353 00354 *Key = NULL; 00355 00356 if (*KeyName == L'\\') 00357 { 00358 KeyName++; 00359 CurrentKey = RootKey; 00360 } 00361 else if (ParentKey == NULL) 00362 { 00363 CurrentKey = RootKey; 00364 } 00365 else 00366 { 00367 CurrentKey = ParentKey; 00368 } 00369 00370 /* Check whether current key is a link */ 00371 if (CurrentKey->DataType == REG_LINK) 00372 { 00373 CurrentKey = (FRLDRHKEY)CurrentKey->Data; 00374 } 00375 00376 while (*KeyName != 0) 00377 { 00378 TRACE("KeyName '%S'\n", KeyName); 00379 00380 if (*KeyName == L'\\') KeyName++; 00381 p = wcschr(KeyName, L'\\'); 00382 if ((p != NULL) && (p != KeyName)) 00383 { 00384 subkeyLength = p - KeyName; 00385 stringLength = subkeyLength + 1; 00386 name = KeyName; 00387 } 00388 else 00389 { 00390 subkeyLength = wcslen(KeyName); 00391 stringLength = subkeyLength; 00392 name = KeyName; 00393 } 00394 NameSize = (ULONG)((subkeyLength + 1) * sizeof(WCHAR)); 00395 00396 Ptr = CurrentKey->SubKeyList.Flink; 00397 while (Ptr != &CurrentKey->SubKeyList) 00398 { 00399 TRACE("Ptr 0x%x\n", Ptr); 00400 00401 SearchKey = CONTAINING_RECORD(Ptr, KEY, KeyList); 00402 00403 TRACE("SearchKey 0x%x\n", SearchKey); 00404 TRACE("Searching '%S'\n", SearchKey->Name); 00405 00406 if (SearchKey->NameSize == NameSize && 00407 _wcsnicmp(SearchKey->Name, name, subkeyLength) == 0) break; 00408 00409 Ptr = Ptr->Flink; 00410 } 00411 00412 if (Ptr == &CurrentKey->SubKeyList) 00413 { 00414 return ERROR_PATH_NOT_FOUND; 00415 } 00416 else 00417 { 00418 CurrentKey = SearchKey; 00419 00420 /* Check whether current key is a link */ 00421 if (CurrentKey->DataType == REG_LINK) 00422 { 00423 CurrentKey = (FRLDRHKEY)CurrentKey->Data; 00424 } 00425 } 00426 00427 KeyName = KeyName + stringLength; 00428 } 00429 00430 if (Key != NULL) 00431 *Key = CurrentKey; 00432 00433 return ERROR_SUCCESS; 00434 } 00435 00436 00437 LONG 00438 RegSetValue(FRLDRHKEY Key, 00439 PCWSTR ValueName, 00440 ULONG Type, 00441 PCSTR Data, 00442 ULONG DataSize) 00443 { 00444 PLIST_ENTRY Ptr; 00445 PVALUE Value = NULL; 00446 00447 TRACE("Key 0x%p, ValueName '%S', Type %ld, Data 0x%p, DataSize %ld\n", 00448 Key, ValueName, Type, Data, DataSize); 00449 00450 if ((ValueName == NULL) || (*ValueName == 0)) 00451 { 00452 /* set default value */ 00453 if ((Key->Data != NULL) && (Key->DataSize > sizeof(PUCHAR))) 00454 { 00455 MmHeapFree(Key->Data); 00456 } 00457 00458 if (DataSize <= sizeof(PUCHAR)) 00459 { 00460 Key->DataSize = DataSize; 00461 Key->DataType = Type; 00462 memcpy(&Key->Data, Data, DataSize); 00463 } 00464 else 00465 { 00466 Key->Data = MmHeapAlloc(DataSize); 00467 Key->DataSize = DataSize; 00468 Key->DataType = Type; 00469 memcpy(Key->Data, Data, DataSize); 00470 } 00471 } 00472 else 00473 { 00474 /* set non-default value */ 00475 Ptr = Key->ValueList.Flink; 00476 while (Ptr != &Key->ValueList) 00477 { 00478 Value = CONTAINING_RECORD(Ptr, VALUE, ValueList); 00479 00480 TRACE("Value->Name '%S'\n", Value->Name); 00481 00482 if (_wcsicmp(Value->Name, ValueName) == 0) break; 00483 00484 Ptr = Ptr->Flink; 00485 } 00486 00487 if (Ptr == &Key->ValueList) 00488 { 00489 /* add new value */ 00490 TRACE("No value found - adding new value\n"); 00491 00492 Value = (PVALUE)MmHeapAlloc(sizeof(VALUE)); 00493 if (Value == NULL) return ERROR_OUTOFMEMORY; 00494 00495 InsertTailList(&Key->ValueList, &Value->ValueList); 00496 Key->ValueCount++; 00497 00498 Value->NameSize = (ULONG)(wcslen(ValueName)+1) * sizeof(WCHAR); 00499 Value->Name = MmHeapAlloc(Value->NameSize); 00500 if (Value->Name == NULL) return ERROR_OUTOFMEMORY; 00501 wcscpy(Value->Name, ValueName); 00502 Value->DataType = REG_NONE; 00503 Value->DataSize = 0; 00504 Value->Data = NULL; 00505 } 00506 00507 /* set new value */ 00508 if ((Value->Data != NULL) && (Value->DataSize > sizeof(PUCHAR))) 00509 { 00510 MmHeapFree(Value->Data); 00511 } 00512 00513 if (DataSize <= sizeof(PUCHAR)) 00514 { 00515 Value->DataSize = DataSize; 00516 Value->DataType = Type; 00517 memcpy(&Value->Data, Data, DataSize); 00518 } 00519 else 00520 { 00521 Value->Data = MmHeapAlloc(DataSize); 00522 if (Value->Data == NULL) return ERROR_OUTOFMEMORY; 00523 Value->DataType = Type; 00524 Value->DataSize = DataSize; 00525 memcpy(Value->Data, Data, DataSize); 00526 } 00527 } 00528 return(ERROR_SUCCESS); 00529 } 00530 00531 00532 LONG 00533 RegQueryValue(FRLDRHKEY Key, 00534 PCWSTR ValueName, 00535 ULONG* Type, 00536 PUCHAR Data, 00537 ULONG* DataSize) 00538 { 00539 ULONG Size; 00540 PLIST_ENTRY Ptr; 00541 PVALUE Value = NULL; 00542 00543 if ((ValueName == NULL) || (*ValueName == 0)) 00544 { 00545 /* query default value */ 00546 if (Key->Data == NULL) return ERROR_INVALID_PARAMETER; 00547 00548 if (Type != NULL) 00549 *Type = Key->DataType; 00550 if ((Data != NULL) && (DataSize != NULL)) 00551 { 00552 if (Key->DataSize <= sizeof(PUCHAR)) 00553 { 00554 Size = min(Key->DataSize, *DataSize); 00555 memcpy(Data, &Key->Data, Size); 00556 *DataSize = Size; 00557 } 00558 else 00559 { 00560 Size = min(Key->DataSize, *DataSize); 00561 memcpy(Data, Key->Data, Size); 00562 *DataSize = Size; 00563 } 00564 } 00565 else if ((Data == NULL) && (DataSize != NULL)) 00566 { 00567 *DataSize = Key->DataSize; 00568 } 00569 } 00570 else 00571 { 00572 /* query non-default value */ 00573 Ptr = Key->ValueList.Flink; 00574 while (Ptr != &Key->ValueList) 00575 { 00576 Value = CONTAINING_RECORD(Ptr, VALUE, ValueList); 00577 00578 TRACE("Searching for '%S'. Value name '%S'\n", ValueName, Value->Name); 00579 00580 if (_wcsicmp(Value->Name, ValueName) == 0) break; 00581 00582 Ptr = Ptr->Flink; 00583 } 00584 00585 if (Ptr == &Key->ValueList) return ERROR_INVALID_PARAMETER; 00586 00587 if (Type != NULL) *Type = Value->DataType; 00588 if ((Data != NULL) && (DataSize != NULL)) 00589 { 00590 if (Value->DataSize <= sizeof(PUCHAR)) 00591 { 00592 Size = min(Value->DataSize, *DataSize); 00593 memcpy(Data, &Value->Data, Size); 00594 *DataSize = Size; 00595 } 00596 else 00597 { 00598 Size = min(Value->DataSize, *DataSize); 00599 memcpy(Data, Value->Data, Size); 00600 *DataSize = Size; 00601 } 00602 } 00603 else if ((Data == NULL) && (DataSize != NULL)) 00604 { 00605 *DataSize = Value->DataSize; 00606 } 00607 } 00608 00609 return ERROR_SUCCESS; 00610 } 00611 00612 00613 LONG 00614 RegDeleteValue(FRLDRHKEY Key, 00615 PCWSTR ValueName) 00616 { 00617 PLIST_ENTRY Ptr; 00618 PVALUE Value = NULL; 00619 00620 if ((ValueName == NULL) || (*ValueName == 0)) 00621 { 00622 /* delete default value */ 00623 if (Key->Data != NULL) MmFreeMemory(Key->Data); 00624 Key->Data = NULL; 00625 Key->DataSize = 0; 00626 Key->DataType = 0; 00627 } 00628 else 00629 { 00630 /* delete non-default value */ 00631 Ptr = Key->ValueList.Flink; 00632 while (Ptr != &Key->ValueList) 00633 { 00634 Value = CONTAINING_RECORD(Ptr, VALUE, ValueList); 00635 if (_wcsicmp(Value->Name, ValueName) == 0) break; 00636 00637 Ptr = Ptr->Flink; 00638 } 00639 00640 if (Ptr == &Key->ValueList) return ERROR_INVALID_PARAMETER; 00641 00642 /* delete value */ 00643 Key->ValueCount--; 00644 if (Value->Name != NULL) MmFreeMemory(Value->Name); 00645 Value->Name = NULL; 00646 Value->NameSize = 0; 00647 00648 if (Value->DataSize > sizeof(PUCHAR)) 00649 { 00650 if (Value->Data != NULL) MmFreeMemory(Value->Data); 00651 } 00652 Value->Data = NULL; 00653 Value->DataSize = 0; 00654 Value->DataType = 0; 00655 00656 RemoveEntryList(&Value->ValueList); 00657 MmFreeMemory(Value); 00658 } 00659 return ERROR_SUCCESS; 00660 } 00661 00662 00663 LONG 00664 RegEnumValue(FRLDRHKEY Key, 00665 ULONG Index, 00666 PWCHAR ValueName, 00667 ULONG* NameSize, 00668 ULONG* Type, 00669 PUCHAR Data, 00670 ULONG* DataSize) 00671 { 00672 PLIST_ENTRY Ptr; 00673 PVALUE Value; 00674 ULONG Count = 0; 00675 00676 if (Key->Data != NULL) 00677 { 00678 if (Index > 0) 00679 { 00680 Index--; 00681 } 00682 else 00683 { 00684 /* enumerate default value */ 00685 if (ValueName != NULL) *ValueName = 0; 00686 if (Type != NULL) *Type = Key->DataType; 00687 if (Data != NULL) 00688 { 00689 if (Key->DataSize <= sizeof(PUCHAR)) 00690 { 00691 memcpy(Data, &Key->Data, min(Key->DataSize, *DataSize)); 00692 } 00693 else 00694 { 00695 memcpy(Data, Key->Data, min(Key->DataSize, *DataSize)); 00696 } 00697 } 00698 00699 if (DataSize != NULL) *DataSize = min(Key->DataSize, *DataSize); 00700 00701 return ERROR_SUCCESS; 00702 } 00703 } 00704 00705 Ptr = Key->ValueList.Flink; 00706 while (Ptr != &Key->ValueList) 00707 { 00708 if (Index == Count) break; 00709 00710 Count++; 00711 Ptr = Ptr->Flink; 00712 } 00713 00714 if (Ptr == &Key->ValueList) return ERROR_NO_MORE_ITEMS; 00715 00716 Value = CONTAINING_RECORD(Ptr, VALUE, ValueList); 00717 00718 /* enumerate non-default value */ 00719 if (ValueName != NULL) 00720 { 00721 memcpy(ValueName, Value->Name, min(Value->NameSize, *NameSize)); 00722 } 00723 if (Type != NULL) *Type = Value->DataType; 00724 00725 if (Data != NULL) 00726 { 00727 if (Value->DataSize <= sizeof(PUCHAR)) 00728 { 00729 memcpy(Data, &Value->Data, min(Value->DataSize, *DataSize)); 00730 } 00731 else 00732 { 00733 memcpy(Data, Value->Data, min(Value->DataSize, *DataSize)); 00734 } 00735 } 00736 00737 if (DataSize != NULL) *DataSize = min(Value->DataSize, *DataSize); 00738 00739 return ERROR_SUCCESS; 00740 } 00741 00742 00743 ULONG 00744 RegGetSubKeyCount (FRLDRHKEY Key) 00745 { 00746 return Key->SubKeyCount; 00747 } 00748 00749 00750 ULONG 00751 RegGetValueCount (FRLDRHKEY Key) 00752 { 00753 if (Key->DataSize != 0) return Key->ValueCount + 1; 00754 00755 return Key->ValueCount; 00756 } 00757 00758 /* EOF */ Generated on Sun May 27 2012 04:17:06 for ReactOS by
1.7.6.1
|