ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

settings.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS kernel
00003  *  Copyright (C) 2004 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 /* COPYRIGHT:       See COPYING in the top level directory
00020  * PROJECT:         ReactOS text-mode setup
00021  * FILE:            subsys/system/usetup/settings.c
00022  * PURPOSE:         Device settings support functions
00023  * PROGRAMMERS:     Eric Kohl
00024  *                  Colin Finck
00025  */
00026 
00027 /* INCLUDES *****************************************************************/
00028 
00029 #include "usetup.h"
00030 
00031 #define NDEBUG
00032 #include <debug.h>
00033 
00034 /* FUNCTIONS ****************************************************************/
00035 
00036 static BOOLEAN
00037 IsAcpiComputer(VOID)
00038 {
00039    UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
00040    UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
00041    UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS");
00042    OBJECT_ATTRIBUTES ObjectAttributes;
00043    PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
00044    ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
00045    PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
00046    ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
00047    ULONG RequiredSize;
00048    ULONG IndexDevice = 0;
00049    UNICODE_STRING DeviceName, ValueName;
00050    HANDLE hDevicesKey = NULL;
00051    HANDLE hDeviceKey = NULL;
00052    NTSTATUS Status;
00053    BOOLEAN ret = FALSE;
00054 
00055    InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL);
00056    Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
00057    if (!NT_SUCCESS(Status))
00058    {
00059       DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status);
00060       goto cleanup;
00061    }
00062 
00063    pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength);
00064    if (!pDeviceInformation)
00065    {
00066       DPRINT("RtlAllocateHeap() failed\n");
00067       Status = STATUS_NO_MEMORY;
00068       goto cleanup;
00069    }
00070 
00071    pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength);
00072    if (!pDeviceInformation)
00073    {
00074       DPRINT("RtlAllocateHeap() failed\n");
00075       Status = STATUS_NO_MEMORY;
00076       goto cleanup;
00077    }
00078 
00079    while (TRUE)
00080    {
00081       Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
00082       if (Status == STATUS_NO_MORE_ENTRIES)
00083          break;
00084       else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
00085       {
00086          RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation);
00087          DeviceInfoLength = RequiredSize;
00088          pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength);
00089          if (!pDeviceInformation)
00090          {
00091             DPRINT("RtlAllocateHeap() failed\n");
00092             Status = STATUS_NO_MEMORY;
00093             goto cleanup;
00094          }
00095          Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
00096       }
00097       if (!NT_SUCCESS(Status))
00098       {
00099          DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status);
00100          goto cleanup;
00101       }
00102       IndexDevice++;
00103 
00104       /* Open device key */
00105       DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
00106       DeviceName.Buffer = pDeviceInformation->Name;
00107       InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL);
00108       Status = NtOpenKey(
00109          &hDeviceKey,
00110          KEY_QUERY_VALUE,
00111          &ObjectAttributes);
00112       if (!NT_SUCCESS(Status))
00113       {
00114          DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status);
00115          goto cleanup;
00116       }
00117 
00118       /* Read identifier */
00119       Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
00120       if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
00121       {
00122          RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation);
00123          ValueInfoLength = RequiredSize;
00124          pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength);
00125          if (!pValueInformation)
00126          {
00127             DPRINT("RtlAllocateHeap() failed\n");
00128             Status = STATUS_NO_MEMORY;
00129             goto cleanup;
00130          }
00131          Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
00132       }
00133       if (!NT_SUCCESS(Status))
00134       {
00135          DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status);
00136          goto nextdevice;
00137       }
00138       else if (pValueInformation->Type != REG_SZ)
00139       {
00140          DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
00141          goto nextdevice;
00142       }
00143 
00144       ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength;
00145       ValueName.Buffer = (PWCHAR)pValueInformation->Data;
00146       if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
00147          ValueName.Length -= sizeof(WCHAR);
00148       if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0)
00149       {
00150          DPRINT("Found ACPI BIOS\n");
00151          ret = TRUE;
00152          goto cleanup;
00153       }
00154 
00155 nextdevice:
00156       NtClose(hDeviceKey);
00157       hDeviceKey = NULL;
00158    }
00159 
00160 cleanup:
00161    if (pDeviceInformation)
00162       RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation);
00163    if (pValueInformation)
00164       RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation);
00165    if (hDevicesKey)
00166       NtClose(hDevicesKey);
00167    if (hDeviceKey)
00168       NtClose(hDeviceKey);
00169    return ret;
00170 }
00171 
00172 
00173 static BOOLEAN
00174 GetComputerIdentifier(PWSTR Identifier,
00175                       ULONG IdentifierLength)
00176 {
00177     OBJECT_ATTRIBUTES ObjectAttributes;
00178     UNICODE_STRING KeyName;
00179     LPCWSTR ComputerIdentifier;
00180     HANDLE ProcessorsKey;
00181     PKEY_FULL_INFORMATION pFullInfo;
00182     ULONG Size, SizeNeeded;
00183     NTSTATUS Status;
00184 
00185     DPRINT("GetComputerIdentifier() called\n");
00186 
00187     Size = sizeof(KEY_FULL_INFORMATION);
00188     pFullInfo = (PKEY_FULL_INFORMATION)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
00189     if (!pFullInfo)
00190     {
00191         DPRINT("RtlAllocateHeap() failed\n");
00192         return FALSE;
00193     }
00194 
00195     /* Open the processors key */
00196     RtlInitUnicodeString(&KeyName,
00197                          L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
00198     InitializeObjectAttributes(&ObjectAttributes,
00199                                &KeyName,
00200                                OBJ_CASE_INSENSITIVE,
00201                                NULL,
00202                                NULL);
00203 
00204     Status = NtOpenKey(&ProcessorsKey,
00205                        KEY_QUERY_VALUE ,
00206                        &ObjectAttributes);
00207     if (!NT_SUCCESS(Status))
00208     {
00209         DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status);
00210         RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
00211         return FALSE;
00212     }
00213 
00214     /* Get number of subkeys */
00215     Status = NtQueryKey(
00216         ProcessorsKey,
00217         KeyFullInformation,
00218         pFullInfo,
00219         Size,
00220         &Size);
00221     NtClose(ProcessorsKey);
00222 
00223     if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
00224     {
00225         DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status);
00226         RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
00227         return FALSE;
00228     }
00229 
00230     /* Find computer identifier */
00231     if (pFullInfo->SubKeys == 0)
00232     {
00233         /* Something strange happened. No processor detected */
00234         RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
00235         return FALSE;
00236     }
00237 
00238     if (IsAcpiComputer())
00239     {
00240         if (pFullInfo->SubKeys == 1)
00241         {
00242             /* Computer is mono-CPU */
00243             ComputerIdentifier = L"ACPI UP";
00244         }
00245         else
00246         {
00247             /* Computer is multi-CPUs */
00248             ComputerIdentifier = L"ACPI MP";
00249         }
00250     }
00251     else
00252     {
00253         if (pFullInfo->SubKeys == 1)
00254         {
00255             /* Computer is mono-CPU */
00256             ComputerIdentifier = L"PC UP";
00257         }
00258         else
00259         {
00260             /* Computer is multi-CPUs */
00261             ComputerIdentifier = L"PC MP";
00262         }
00263     }
00264 
00265     RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
00266 
00267     /* Copy computer identifier to return buffer */
00268     SizeNeeded = (wcslen(ComputerIdentifier) + 1) * sizeof(WCHAR);
00269     if (SizeNeeded > IdentifierLength)
00270         return FALSE;
00271 
00272     RtlCopyMemory(Identifier, ComputerIdentifier, SizeNeeded);
00273 
00274     return TRUE;
00275 }
00276 
00277 
00278 PGENERIC_LIST
00279 CreateComputerTypeList(HINF InfFile)
00280 {
00281     CHAR Buffer[128];
00282     PGENERIC_LIST List;
00283     INFCONTEXT Context;
00284     PWCHAR KeyName;
00285     PWCHAR KeyValue;
00286     PWCHAR UserData;
00287     WCHAR ComputerIdentifier[128];
00288     WCHAR ComputerKey[32];
00289 
00290     /* Get the computer identification */
00291     if (!GetComputerIdentifier(ComputerIdentifier, 128))
00292     {
00293         ComputerIdentifier[0] = 0;
00294     }
00295 
00296     DPRINT("Computer identifier: '%S'\n", ComputerIdentifier);
00297 
00298     /* Search for matching device identifier */
00299     if (!SetupFindFirstLineW(InfFile, L"Map.Computer", NULL, &Context))
00300     {
00301         /* FIXME: error message */
00302         return NULL;
00303     }
00304 
00305     do
00306     {
00307         if (!INF_GetDataField(&Context, 1, &KeyValue))
00308         {
00309             /* FIXME: Handle error! */
00310             DPRINT("INF_GetDataField() failed\n");
00311             return NULL;
00312         }
00313 
00314         DPRINT("KeyValue: %S\n", KeyValue);
00315         if (wcsstr(ComputerIdentifier, KeyValue))
00316         {
00317             if (!INF_GetDataField(&Context, 0, &KeyName))
00318             {
00319                 /* FIXME: Handle error! */
00320                 DPRINT("INF_GetDataField() failed\n");
00321                 return NULL;
00322             }
00323 
00324             DPRINT("Computer key: %S\n", KeyName);
00325             wcscpy(ComputerKey, KeyName);
00326         }
00327     } while (SetupFindNextLine(&Context, &Context));
00328 
00329     List = CreateGenericList();
00330     if (List == NULL)
00331         return NULL;
00332 
00333     if (!SetupFindFirstLineW (InfFile, L"Computer", NULL, &Context))
00334     {
00335         DestroyGenericList(List, FALSE);
00336         return NULL;
00337     }
00338 
00339     do
00340     {
00341         if (!INF_GetData (&Context, &KeyName, &KeyValue))
00342         {
00343             /* FIXME: Handle error! */
00344             DPRINT("INF_GetData() failed\n");
00345             break;
00346         }
00347 
00348         UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
00349                                             0,
00350                                             (wcslen(KeyName) + 1) * sizeof(WCHAR));
00351         if (UserData == NULL)
00352         {
00353             /* FIXME: Handle error! */
00354         }
00355 
00356         wcscpy(UserData, KeyName);
00357 
00358         sprintf(Buffer, "%S", KeyValue);
00359         AppendGenericListEntry(List, Buffer, UserData,
00360                                _wcsicmp(KeyName, ComputerKey) ? FALSE : TRUE);
00361     } while (SetupFindNextLine(&Context, &Context));
00362 
00363     return List;
00364 }
00365 
00366 
00367 static BOOLEAN
00368 GetDisplayIdentifier(PWSTR Identifier,
00369     ULONG IdentifierLength)
00370 {
00371     OBJECT_ATTRIBUTES ObjectAttributes;
00372     UNICODE_STRING KeyName;
00373     WCHAR Buffer[32];
00374     HANDLE BusKey;
00375     HANDLE BusInstanceKey;
00376     HANDLE ControllerKey;
00377     HANDLE ControllerInstanceKey;
00378     ULONG BusInstance;
00379     ULONG ControllerInstance;
00380     ULONG BufferLength;
00381     ULONG ReturnedLength;
00382     PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
00383     NTSTATUS Status;
00384 
00385     DPRINT("GetDisplayIdentifier() called\n");
00386 
00387     /* Open the bus key */
00388     RtlInitUnicodeString(&KeyName,
00389                          L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
00390     InitializeObjectAttributes(&ObjectAttributes,
00391                                &KeyName,
00392                                OBJ_CASE_INSENSITIVE,
00393                                NULL,
00394                                NULL);
00395 
00396     Status = NtOpenKey(&BusKey,
00397                        KEY_ENUMERATE_SUB_KEYS,
00398                        &ObjectAttributes);
00399     if (!NT_SUCCESS(Status))
00400     {
00401         DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
00402         return FALSE;
00403     }
00404 
00405     BusInstance = 0;
00406     while (TRUE)
00407     {
00408         swprintf(Buffer, L"%lu", BusInstance);
00409         RtlInitUnicodeString(&KeyName,
00410                              Buffer);
00411         InitializeObjectAttributes(&ObjectAttributes,
00412                                    &KeyName,
00413                                    OBJ_CASE_INSENSITIVE,
00414                                    BusKey,
00415                                    NULL);
00416 
00417         Status = NtOpenKey(&BusInstanceKey,
00418                            KEY_ENUMERATE_SUB_KEYS,
00419                            &ObjectAttributes);
00420         if (!NT_SUCCESS(Status))
00421         {
00422             DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
00423             NtClose(BusKey);
00424             return FALSE;
00425         }
00426 
00427         /* Open the controller type key */
00428         RtlInitUnicodeString(&KeyName,
00429                              L"DisplayController");
00430         InitializeObjectAttributes(&ObjectAttributes,
00431                                    &KeyName,
00432                                    OBJ_CASE_INSENSITIVE,
00433                                    BusInstanceKey,
00434                                    NULL);
00435 
00436         Status = NtOpenKey(&ControllerKey,
00437                            KEY_ENUMERATE_SUB_KEYS,
00438                            &ObjectAttributes);
00439         if (NT_SUCCESS(Status))
00440         {
00441             ControllerInstance = 0;
00442 
00443             while (TRUE)
00444             {
00445                 /* Open the pointer controller instance key */
00446                 swprintf(Buffer, L"%lu", ControllerInstance);
00447                 RtlInitUnicodeString(&KeyName,
00448                                      Buffer);
00449                 InitializeObjectAttributes(&ObjectAttributes,
00450                                            &KeyName,
00451                                            OBJ_CASE_INSENSITIVE,
00452                                            ControllerKey,
00453                                            NULL);
00454 
00455                 Status = NtOpenKey(&ControllerInstanceKey,
00456                                    KEY_QUERY_VALUE,
00457                                    &ObjectAttributes);
00458                 if (!NT_SUCCESS(Status))
00459                 {
00460                     DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
00461                     NtClose(ControllerKey);
00462                     NtClose(BusInstanceKey);
00463                     NtClose(BusKey);
00464                     return FALSE;
00465                 }
00466 
00467                 /* Get controller identifier */
00468                 RtlInitUnicodeString(&KeyName,
00469                                      L"Identifier");
00470 
00471                 BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
00472                                256 * sizeof(WCHAR);
00473                 ValueInfo = (KEY_VALUE_PARTIAL_INFORMATION*) RtlAllocateHeap(RtlGetProcessHeap(),
00474                                                                              0,
00475                                                                              BufferLength);
00476                 if (ValueInfo == NULL)
00477                 {
00478                     DPRINT("RtlAllocateHeap() failed\n");
00479                     NtClose(ControllerInstanceKey);
00480                     NtClose(ControllerKey);
00481                     NtClose(BusInstanceKey);
00482                     NtClose(BusKey);
00483                     return FALSE;
00484                 }
00485 
00486                 Status = NtQueryValueKey(ControllerInstanceKey,
00487                                          &KeyName,
00488                                          KeyValuePartialInformation,
00489                                          ValueInfo,
00490                                          BufferLength,
00491                                          &ReturnedLength);
00492                 if (NT_SUCCESS(Status))
00493                 {
00494                     DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);
00495 
00496                     BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength);
00497                     RtlCopyMemory (Identifier,
00498                                    ValueInfo->Data,
00499                                    BufferLength * sizeof(WCHAR));
00500                     Identifier[BufferLength] = 0;
00501 
00502                     RtlFreeHeap(RtlGetProcessHeap(),
00503                                 0,
00504                                 ValueInfo);
00505 
00506                     NtClose(ControllerInstanceKey);
00507                     NtClose(ControllerKey);
00508                     NtClose(BusInstanceKey);
00509                     NtClose(BusKey);
00510                     return TRUE;
00511                 }
00512 
00513                 NtClose(ControllerInstanceKey);
00514 
00515                 ControllerInstance++;
00516             }
00517 
00518             NtClose(ControllerKey);
00519         }
00520 
00521         NtClose(BusInstanceKey);
00522 
00523         BusInstance++;
00524     }
00525 
00526     NtClose(BusKey);
00527 
00528     return FALSE;
00529 }
00530 
00531 
00532 PGENERIC_LIST
00533 CreateDisplayDriverList(HINF InfFile)
00534 {
00535     CHAR Buffer[128];
00536     PGENERIC_LIST List;
00537     INFCONTEXT Context;
00538     PWCHAR KeyName;
00539     PWCHAR KeyValue;
00540     PWCHAR UserData;
00541     WCHAR DisplayIdentifier[128];
00542     WCHAR DisplayKey[32];
00543 
00544     /* Get the display identification */
00545     if (!GetDisplayIdentifier(DisplayIdentifier, 128))
00546     {
00547         DisplayIdentifier[0] = 0;
00548     }
00549 
00550     DPRINT("Display identifier: '%S'\n", DisplayIdentifier);
00551 
00552     /* Search for matching device identifier */
00553     if (!SetupFindFirstLineW(InfFile, L"Map.Display", NULL, &Context))
00554     {
00555         /* FIXME: error message */
00556         return NULL;
00557     }
00558 
00559     do
00560     {
00561         if (!INF_GetDataField(&Context, 1, &KeyValue))
00562         {
00563             /* FIXME: Handle error! */
00564             DPRINT("INF_GetDataField() failed\n");
00565             return NULL;
00566         }
00567 
00568         DPRINT("KeyValue: %S\n", KeyValue);
00569         if (wcsstr(DisplayIdentifier, KeyValue))
00570         {
00571             if (!INF_GetDataField(&Context, 0, &KeyName))
00572             {
00573                 /* FIXME: Handle error! */
00574                 DPRINT("INF_GetDataField() failed\n");
00575                 return NULL;
00576             }
00577 
00578             DPRINT("Display key: %S\n", KeyName);
00579             wcscpy(DisplayKey, KeyName);
00580         }
00581     } while (SetupFindNextLine(&Context, &Context));
00582 
00583     List = CreateGenericList();
00584     if (List == NULL)
00585         return NULL;
00586 
00587     if (!SetupFindFirstLineW (InfFile, L"Display", NULL, &Context))
00588     {
00589         DestroyGenericList(List, FALSE);
00590         return NULL;
00591     }
00592 
00593     do
00594     {
00595         if (!INF_GetDataField(&Context, 0, &KeyName))
00596         {
00597             DPRINT1("INF_GetDataField() failed\n");
00598             break;
00599         }
00600 
00601         if (!INF_GetDataField(&Context, 1, &KeyValue))
00602         {
00603             DPRINT1("INF_GetDataField() failed\n");
00604             break;
00605         }
00606 
00607         UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
00608                                             0,
00609                                             (wcslen(KeyName) + 1) * sizeof(WCHAR));
00610         if (UserData == NULL)
00611         {
00612             DPRINT1("RtlAllocateHeap() failed\n");
00613             DestroyGenericList(List, TRUE);
00614             return NULL;
00615         }
00616 
00617         wcscpy(UserData, KeyName);
00618 
00619         sprintf(Buffer, "%S", KeyValue);
00620         AppendGenericListEntry(List,
00621                                Buffer,
00622                                UserData,
00623                                _wcsicmp(KeyName, DisplayKey) ? FALSE : TRUE);
00624     } while (SetupFindNextLine(&Context, &Context));
00625 
00626 #if 0
00627     AppendGenericListEntry(List, "Other display driver", NULL, TRUE);
00628 #endif
00629 
00630     return List;
00631 }
00632 
00633 BOOLEAN
00634 ProcessComputerFiles(HINF InfFile, PGENERIC_LIST List, PWCHAR* AdditionalSectionName)
00635 {
00636     PGENERIC_LIST_ENTRY Entry;
00637     static WCHAR SectionName[128];
00638 
00639     DPRINT("ProcessComputerFiles() called\n");
00640 
00641     Entry = GetCurrentListEntry(List);
00642     if (Entry == NULL)
00643     {
00644         DPRINT("GetCurrentListEntry() failed\n");
00645         return FALSE;
00646     }
00647 
00648     wcscpy(SectionName, L"Files.");
00649     wcscat(SectionName, (const wchar_t*)GetListEntryUserData(Entry));
00650     *AdditionalSectionName = SectionName;
00651 
00652     return TRUE;
00653 }
00654 
00655 
00656 BOOLEAN
00657 ProcessDisplayRegistry(HINF InfFile, PGENERIC_LIST List)
00658 {
00659     PGENERIC_LIST_ENTRY Entry;
00660     INFCONTEXT Context;
00661     PWCHAR ServiceName;
00662     ULONG StartValue;
00663     NTSTATUS Status;
00664     WCHAR RegPath [255];
00665     PWCHAR Buffer;
00666     ULONG Width, Height, Bpp;
00667 
00668     DPRINT("ProcessDisplayRegistry() called\n");
00669 
00670     Entry = GetCurrentListEntry(List);
00671     if (Entry == NULL)
00672     {
00673         DPRINT("GetCurrentListEntry() failed\n");
00674         return FALSE;
00675     }
00676 
00677     if (!SetupFindFirstLineW(InfFile, L"Display", (WCHAR*)GetListEntryUserData(Entry), &Context))
00678     {
00679         DPRINT("SetupFindFirstLineW() failed\n");
00680         return FALSE;
00681     }
00682 
00683     /* Enable the right driver */
00684     if (!INF_GetDataField(&Context, 3, &ServiceName))
00685     {
00686         DPRINT("INF_GetDataField() failed\n");
00687         return FALSE;
00688     }
00689 
00690     ASSERT(wcslen(ServiceName) < 10);
00691     DPRINT("Service name: %S\n", ServiceName);
00692 
00693     StartValue = 1;
00694     Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
00695         ServiceName,
00696         L"Start",
00697         REG_DWORD,
00698         &StartValue,
00699         sizeof(ULONG));
00700 
00701     if (!NT_SUCCESS(Status))
00702     {
00703         DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
00704         return FALSE;
00705     }
00706 
00707     /* Set the resolution */
00708     swprintf(RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName);
00709 
00710     if (!INF_GetDataField(&Context, 4, &Buffer))
00711     {
00712         DPRINT("INF_GetDataField() failed\n");
00713         return FALSE;
00714     }
00715 
00716     Width = wcstoul(Buffer, NULL, 10);
00717     Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
00718         RegPath,
00719         L"DefaultSettings.XResolution",
00720         REG_DWORD,
00721         &Width,
00722         sizeof(ULONG));
00723     if (!NT_SUCCESS(Status))
00724     {
00725         DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
00726         return FALSE;
00727     }
00728 
00729     if (!INF_GetDataField(&Context, 5, &Buffer))
00730     {
00731         DPRINT("INF_GetDataField() failed\n");
00732         return FALSE;
00733     }
00734 
00735     Height = wcstoul(Buffer, 0, 0);
00736     Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
00737         RegPath,
00738         L"DefaultSettings.YResolution",
00739         REG_DWORD,
00740         &Height,
00741         sizeof(ULONG));
00742     if (!NT_SUCCESS(Status))
00743     {
00744         DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
00745         return FALSE;
00746     }
00747 
00748     if (!INF_GetDataField(&Context, 6, &Buffer))
00749     {
00750         DPRINT("INF_GetDataField() failed\n");
00751         return FALSE;
00752     }
00753 
00754     Bpp = wcstoul(Buffer, 0, 0);
00755     Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
00756         RegPath,
00757         L"DefaultSettings.BitsPerPel",
00758         REG_DWORD,
00759         &Bpp,
00760         sizeof(ULONG));
00761     if (!NT_SUCCESS(Status))
00762     {
00763         DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
00764         return FALSE;
00765     }
00766 
00767     DPRINT("ProcessDisplayRegistry() done\n");
00768 
00769     return TRUE;
00770 }
00771 
00772 
00773 BOOLEAN
00774 ProcessLocaleRegistry(PGENERIC_LIST List)
00775 {
00776     PGENERIC_LIST_ENTRY Entry;
00777     PWCHAR LanguageId;
00778     OBJECT_ATTRIBUTES ObjectAttributes;
00779     UNICODE_STRING KeyName;
00780     UNICODE_STRING ValueName;
00781 
00782     HANDLE KeyHandle;
00783     NTSTATUS Status;
00784 
00785     Entry = GetCurrentListEntry(List);
00786     if (Entry == NULL)
00787         return FALSE;
00788 
00789     LanguageId = (PWCHAR)GetListEntryUserData(Entry);
00790     if (LanguageId == NULL)
00791         return FALSE;
00792 
00793     /* Skip first 4 zeroes */
00794     if (wcslen(LanguageId) >= 4)
00795         LanguageId += 4;
00796 
00797     /* Open the NLS language key */
00798     RtlInitUnicodeString(&KeyName,
00799                          L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
00800 
00801     InitializeObjectAttributes(&ObjectAttributes,
00802                                &KeyName,
00803                                OBJ_CASE_INSENSITIVE,
00804                                NULL,
00805                                NULL);
00806 
00807     Status =  NtOpenKey(&KeyHandle,
00808                         KEY_SET_VALUE,
00809                         &ObjectAttributes);
00810 
00811     if (!NT_SUCCESS(Status))
00812     {
00813         DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
00814         return FALSE;
00815     }
00816 
00817     /* Set default language */
00818     RtlInitUnicodeString(&ValueName,
00819                          L"Default");
00820     Status = NtSetValueKey(KeyHandle,
00821                            &ValueName,
00822                            0,
00823                            REG_SZ,
00824                            (PVOID)LanguageId,
00825                            (wcslen(LanguageId) + 1) * sizeof(WCHAR));
00826     if (!NT_SUCCESS(Status))
00827     {
00828         DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
00829         NtClose(KeyHandle);
00830         return FALSE;
00831     }
00832 
00833     /* Set install language */
00834     RtlInitUnicodeString(&ValueName,
00835                          L"InstallLanguage");
00836     Status = NtSetValueKey (KeyHandle,
00837                             &ValueName,
00838                             0,
00839                             REG_SZ,
00840                             (PVOID)LanguageId,
00841                             (wcslen(LanguageId) + 1) * sizeof(WCHAR));
00842     NtClose(KeyHandle);
00843     if (!NT_SUCCESS(Status))
00844     {
00845         DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
00846         return FALSE;
00847     }
00848 
00849     return TRUE;
00850 }
00851 
00852 
00853 PGENERIC_LIST
00854 CreateKeyboardDriverList(HINF InfFile)
00855 {
00856     CHAR Buffer[128];
00857     PGENERIC_LIST List;
00858     INFCONTEXT Context;
00859     PWCHAR KeyName;
00860     PWCHAR KeyValue;
00861     PWCHAR UserData;
00862 
00863     List = CreateGenericList();
00864     if (List == NULL)
00865         return NULL;
00866 
00867     if (!SetupFindFirstLineW (InfFile, L"Keyboard", NULL, &Context))
00868     {
00869         DestroyGenericList(List, FALSE);
00870         return NULL;
00871     }
00872 
00873     do
00874     {
00875         if (!INF_GetData (&Context, &KeyName, &KeyValue))
00876         {
00877             /* FIXME: Handle error! */
00878             DPRINT("INF_GetData() failed\n");
00879             break;
00880         }
00881 
00882         UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
00883                                             0,
00884                                             (wcslen(KeyName) + 1) * sizeof(WCHAR));
00885         if (UserData == NULL)
00886         {
00887             /* FIXME: Handle error! */
00888         }
00889 
00890         wcscpy(UserData, KeyName);
00891 
00892         sprintf(Buffer, "%S", KeyValue);
00893         AppendGenericListEntry(List, Buffer, UserData, FALSE);
00894     } while (SetupFindNextLine(&Context, &Context));
00895 
00896     return List;
00897 }
00898 
00899 ULONG DefaultLanguageIndex = 0;
00900 
00901 ULONG
00902 GetDefaultLanguageIndex(VOID)
00903 {
00904     return DefaultLanguageIndex;
00905 }
00906 
00907 PGENERIC_LIST
00908 CreateLanguageList(HINF InfFile, WCHAR * DefaultLanguage) 
00909 {
00910     CHAR Buffer[128];
00911     PGENERIC_LIST List;
00912     INFCONTEXT Context;
00913     PWCHAR KeyName;
00914     PWCHAR KeyValue;
00915     PWCHAR UserData = NULL;
00916     ULONG uIndex = 0;
00917 
00918     /* Get default language id */
00919     if (!SetupFindFirstLineW (InfFile, L"NLS", L"DefaultLanguage", &Context))
00920         return NULL;
00921 
00922     if (!INF_GetData (&Context, NULL, &KeyValue))
00923         return NULL;
00924 
00925     wcscpy(DefaultLanguage, KeyValue);
00926 
00927     SelectedLanguageId = KeyValue;
00928 
00929     List = CreateGenericList();
00930     if (List == NULL)
00931         return NULL;
00932 
00933     if (!SetupFindFirstLineW (InfFile, L"Language", NULL, &Context))
00934     {
00935         DestroyGenericList(List, FALSE);
00936         return NULL; 
00937     }
00938 
00939     do
00940     {
00941         if (!INF_GetData (&Context, &KeyName, &KeyValue))
00942         {
00943             /* FIXME: Handle error! */
00944             DPRINT("INF_GetData() failed\n");
00945             break;
00946         }
00947 
00948         if (IsLanguageAvailable(KeyName))
00949         {
00950 
00951             UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
00952                                                 0,
00953                                                 (wcslen(KeyName) + 1) * sizeof(WCHAR));
00954             if (UserData == NULL)
00955             {
00956                 /* FIXME: Handle error! */
00957             }
00958 
00959             wcscpy(UserData, KeyName);
00960 
00961             if (!_wcsicmp(KeyName, DefaultLanguage))
00962                 DefaultLanguageIndex = uIndex;
00963 
00964             sprintf(Buffer, "%S", KeyValue);
00965             AppendGenericListEntry(List,
00966                                    Buffer,
00967                                    UserData,
00968                                    FALSE);
00969             uIndex++;
00970         }
00971     } while (SetupFindNextLine(&Context, &Context));
00972 
00973     /* Only one language available, make it the default one */
00974     if(uIndex == 1 && UserData != NULL)
00975     {
00976         DefaultLanguageIndex = 0;
00977         wcscpy(DefaultLanguage, UserData);
00978     }
00979 
00980     return List;
00981 }
00982 
00983 PGENERIC_LIST
00984 CreateKeyboardLayoutList(HINF InfFile, WCHAR * DefaultKBLayout)
00985 {
00986     CHAR Buffer[128];
00987     PGENERIC_LIST List;
00988     INFCONTEXT Context;
00989     PWCHAR KeyName;
00990     PWCHAR KeyValue;
00991     PWCHAR UserData;
00992     const MUI_LAYOUTS * LayoutsList;
00993     ULONG uIndex = 0;
00994     BOOL KeyboardLayoutsFound = FALSE;
00995 
00996     /* Get default layout id */
00997     if (!SetupFindFirstLineW (InfFile, L"NLS", L"DefaultLayout", &Context))
00998         return NULL;
00999 
01000     if (!INF_GetData (&Context, NULL, &KeyValue))
01001         return NULL;
01002 
01003     wcscpy(DefaultKBLayout, KeyValue);
01004 
01005     List = CreateGenericList();
01006     if (List == NULL)
01007         return NULL;
01008 
01009     LayoutsList = MUIGetLayoutsList();
01010 
01011     do
01012     {
01013         if (!SetupFindFirstLineW(InfFile, L"KeyboardLayout", NULL, &Context))
01014         {
01015             DestroyGenericList(List, FALSE);
01016             return NULL;
01017         }
01018 
01019         do
01020         {
01021             if (!INF_GetData (&Context, &KeyName, &KeyValue))
01022             {
01023                 /* FIXME: Handle error! */
01024                 DPRINT("INF_GetData() failed\n");
01025                 DestroyGenericList(List, FALSE);
01026                 return NULL;
01027             }
01028 
01029             if (_wcsicmp(LayoutsList[uIndex].LayoutID, KeyName) == 0)
01030             {
01031                 UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
01032                                                 0,
01033                                                 (wcslen(KeyName) + 1) * sizeof(WCHAR));
01034 
01035                 if (UserData == NULL)
01036                 {
01037                     /* FIXME: Handle error! */
01038                     DPRINT("RtlAllocateHeap() failed\n");
01039                     DestroyGenericList(List, FALSE);
01040                     return NULL;
01041                 }
01042 
01043                 wcscpy(UserData, KeyName);
01044 
01045                 sprintf(Buffer, "%S", KeyValue);
01046                 AppendGenericListEntry(List,
01047                                        Buffer,
01048                                        UserData,
01049                                        _wcsicmp(KeyName, DefaultKBLayout) ? FALSE : TRUE);
01050                 KeyboardLayoutsFound = TRUE;
01051             }
01052 
01053         } while (SetupFindNextLine(&Context, &Context));
01054 
01055         uIndex++;
01056 
01057     } while (LayoutsList[uIndex].LangID != NULL);
01058 
01059     /* FIXME: Handle this case */
01060     if (!KeyboardLayoutsFound)
01061     {
01062         DPRINT1("No keyboard layouts have been found\n");
01063         DestroyGenericList(List, FALSE);
01064         return NULL;
01065     }
01066 
01067     return List;
01068 }
01069 
01070 BOOLEAN
01071 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List)
01072 {
01073     PGENERIC_LIST_ENTRY Entry;
01074     PWCHAR LayoutId;
01075     const MUI_LAYOUTS * LayoutsList;
01076     MUI_LAYOUTS NewLayoutsList[20];
01077     ULONG uIndex;
01078     ULONG uOldPos = 0;
01079 
01080     Entry = GetCurrentListEntry(List);
01081     if (Entry == NULL)
01082         return FALSE;
01083 
01084     LayoutId = (PWCHAR)GetListEntryUserData(Entry);
01085     if (LayoutId == NULL)
01086         return FALSE;
01087 
01088     LayoutsList = MUIGetLayoutsList();
01089 
01090     if (_wcsicmp(LayoutsList[0].LayoutID, LayoutId) != 0)
01091     {
01092         for (uIndex = 1; LayoutsList[uIndex].LangID != NULL; uIndex++)
01093         {
01094             if (_wcsicmp(LayoutsList[uIndex].LayoutID, LayoutId) == 0)
01095             {
01096                 uOldPos = uIndex;
01097                 continue;
01098             }
01099 
01100             NewLayoutsList[uIndex].LangID   = LayoutsList[uIndex].LangID;
01101             NewLayoutsList[uIndex].LayoutID = LayoutsList[uIndex].LayoutID;
01102         }
01103 
01104         NewLayoutsList[uIndex].LangID    = NULL;
01105         NewLayoutsList[uIndex].LayoutID  = NULL;
01106         NewLayoutsList[uOldPos].LangID   = LayoutsList[0].LangID;
01107         NewLayoutsList[uOldPos].LayoutID = LayoutsList[0].LayoutID;
01108         NewLayoutsList[0].LangID         = LayoutsList[uOldPos].LangID;
01109         NewLayoutsList[0].LayoutID       = LayoutsList[uOldPos].LayoutID;
01110 
01111         return AddKbLayoutsToRegistry(NewLayoutsList);
01112     }
01113 
01114     return TRUE;
01115 }
01116 
01117 
01118 #if 0
01119 BOOLEAN
01120 ProcessKeyboardLayoutFiles(PGENERIC_LIST List)
01121 {
01122     return TRUE;
01123 }
01124 #endif
01125 
01126 BOOLEAN
01127 SetGeoID(PWCHAR Id)
01128 {
01129     OBJECT_ATTRIBUTES ObjectAttributes;
01130     UNICODE_STRING KeyName;
01131     UNICODE_STRING ValueName;
01132     HANDLE KeyHandle;
01133     WCHAR szKeyName[] = L"\\Registry\\User\\.DEFAULT\\Control Panel\\International\\Geo";
01134     WCHAR szValueName[] = L"Nation";
01135     NTSTATUS Status;
01136     RtlInitUnicodeString(&KeyName,
01137                          szKeyName);
01138     InitializeObjectAttributes(&ObjectAttributes,
01139                                &KeyName,
01140                                OBJ_CASE_INSENSITIVE,
01141                                NULL,
01142                                NULL);
01143 
01144     Status =  NtOpenKey(&KeyHandle,
01145                         KEY_SET_VALUE,
01146               &ObjectAttributes);
01147     if(!NT_SUCCESS(Status))
01148     {
01149         DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
01150         return FALSE;
01151     }
01152     RtlInitUnicodeString(&ValueName, szValueName);
01153     Status = NtSetValueKey(KeyHandle,
01154                                    &ValueName,
01155                                    0,
01156                                    REG_SZ,
01157                                    (PVOID)Id,
01158                                    (wcslen(Id) + 1) * sizeof(WCHAR));
01159     NtClose(KeyHandle);
01160     if (!NT_SUCCESS(Status))
01161     {
01162          DPRINT1("NtSetValueKey() failed (Status = %lx)\n", Status);
01163          return FALSE;
01164     }
01165 
01166     return TRUE;
01167 }
01168 
01169 /* EOF */

Generated on Sun May 27 2012 04:16:30 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.