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

powrprof.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 Benjamin Cutler
00003  * Copyright (C) 2008 Dmitry Chapyshev
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library 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 GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  */
00019 
00020 
00021 #include <stdarg.h>
00022 
00023 #define WIN32_NO_STATUS
00024 #include <windows.h>
00025 #define NTOS_MODE_USER
00026 #include <ndk/pofuncs.h>
00027 #include <ndk/rtlfuncs.h>
00028 #include <ndk/setypes.h>
00029 #include <powrprof.h>
00030 #include <wchar.h>
00031 #include <stdio.h>
00032 
00033 #include "wine/debug.h"
00034 #include "wine/unicode.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(powrprof);
00037 
00038 
00039 static const WCHAR szPowerCfgSubKey[] =
00040     L"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
00041 static const WCHAR szUserPowerConfigSubKey[] = 
00042     L"Control Panel\\PowerCfg";
00043 static const WCHAR szCurrentPowerPolicies[] = 
00044     L"CurrentPowerPolicy";
00045 static const WCHAR szPolicies[] = L"Policies";
00046 static const WCHAR szName[] = L"Name";
00047 static const WCHAR szDescription[] = L"Description";
00048 static const WCHAR szSemaphoreName[] = L"PowerProfileRegistrySemaphore";
00049 static const WCHAR szDiskMax[] = L"DiskSpindownMax";
00050 static const WCHAR szDiskMin[] = L"DiskSpindownMin";
00051 static const WCHAR szLastID[] = L"LastID";
00052 
00053 UINT g_LastID = (UINT)-1;
00054 
00055 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy);
00056 
00057 HANDLE PPRegSemaphore = NULL;
00058 
00059 NTSTATUS WINAPI
00060 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel,
00061                        PVOID lpInputBuffer,
00062                        ULONG nInputBufferSize,
00063                        PVOID lpOutputBuffer,
00064                        ULONG nOutputBufferSize)
00065 {
00066     BOOLEAN old;
00067 
00068     //Lohnegrim: In order to get the right results, we have to ajust our Privilegs
00069     RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
00070     RtlAdjustPrivilege(SE_CREATE_PAGEFILE_PRIVILEGE, TRUE, FALSE, &old);
00071 
00072     return NtPowerInformation(InformationLevel,
00073                               lpInputBuffer,
00074                               nInputBufferSize,
00075                               lpOutputBuffer,
00076                               nOutputBufferSize);
00077 }
00078 
00079 BOOLEAN WINAPI
00080 CanUserWritePwrScheme(VOID)
00081 {
00082     HKEY hKey = NULL;
00083     LONG Ret;
00084 
00085     TRACE("()\n");
00086 
00087     Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ | KEY_WRITE, &hKey);
00088     if (Ret != ERROR_SUCCESS)
00089     {
00090         TRACE("RegOpenKeyEx failed: %d\n", Ret);
00091         SetLastError(Ret);
00092         return FALSE;
00093     }
00094 
00095     RegCloseKey(hKey);
00096     return TRUE;
00097 }
00098 
00099 BOOLEAN WINAPI
00100 DeletePwrScheme(UINT uiIndex)
00101 {
00102     WCHAR Buf[MAX_PATH];
00103     UINT Current;
00104     LONG Err;
00105 
00106     swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%d", uiIndex);
00107 
00108     if (!GetActivePwrScheme(&Current))
00109         return FALSE;
00110 
00111     if (Current == uiIndex)
00112     {
00113         SetLastError(ERROR_ACCESS_DENIED);
00114         return FALSE;
00115     }
00116 
00117     Err = RegDeleteKey(HKEY_CURRENT_USER, (LPCTSTR)Buf);
00118     if (Err != ERROR_SUCCESS)
00119     {
00120         TRACE("RegDeleteKey failed: %d\n", Err);
00121         SetLastError(Err);
00122         return FALSE;
00123     }
00124 
00125     return TRUE;
00126 }
00127 
00128 static BOOLEAN
00129 POWRPROF_GetUserPowerPolicy(LPWSTR szNum,
00130                             PUSER_POWER_POLICY puserPwrPolicy,
00131                             DWORD cchName, LPWSTR szName,
00132                             DWORD cchDesc, LPWSTR szDesc)
00133 {
00134     HKEY hSubKey = NULL;
00135     DWORD dwSize;
00136     LONG Err;
00137     WCHAR szPath[MAX_PATH];
00138     BOOL bRet = FALSE;
00139 
00140     swprintf(szPath, L"Control Panel\\PowerCfg\\PowerPolicies\\%s", szNum);
00141 
00142     Err = RegOpenKeyExW(HKEY_CURRENT_USER, szPath, 0, KEY_READ, &hSubKey);
00143     if (Err != ERROR_SUCCESS)
00144     {
00145         ERR("RegOpenKeyExW failed: %d\n", Err);
00146         SetLastError(Err);
00147         return FALSE;
00148     }
00149 
00150     dwSize = cchName * sizeof(WCHAR);
00151     Err = RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szName, &dwSize);
00152     if (Err != ERROR_SUCCESS)
00153     {
00154         ERR("RegQueryValueExW failed: %d\n", Err);
00155         SetLastError(Err);
00156         goto cleanup;
00157     }
00158 
00159     dwSize = cchDesc * sizeof(WCHAR);
00160     Err = RegQueryValueExW(hSubKey, L"Description", NULL, NULL, (LPBYTE)szDesc, &dwSize);
00161     if (Err != ERROR_SUCCESS)
00162     {
00163         ERR("RegQueryValueExW failed: %d\n", Err);
00164         SetLastError(Err);
00165         goto cleanup;
00166     }
00167 
00168     dwSize = sizeof(USER_POWER_POLICY);
00169     Err = RegQueryValueExW(hSubKey, L"Policies", NULL, NULL, (LPBYTE)puserPwrPolicy, &dwSize);
00170     if (Err != ERROR_SUCCESS)
00171     {
00172         ERR("RegQueryValueExW failed: %d\n", Err);
00173         SetLastError(Err);
00174         goto cleanup;
00175     }
00176 
00177     bRet = TRUE;
00178 
00179 cleanup:
00180     RegCloseKey(hSubKey);
00181 
00182     return bRet;
00183 }
00184 
00185 static BOOLEAN
00186 POWRPROF_GetMachinePowerPolicy(LPWSTR szNum, PMACHINE_POWER_POLICY pmachinePwrPolicy)
00187 {
00188     HKEY hKey;
00189     LONG Err;
00190     WCHAR szPath[MAX_PATH];
00191     DWORD dwSize;
00192 
00193     swprintf(szPath, L"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%s", szNum);
00194 
00195     Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey);
00196     if (Err != ERROR_SUCCESS)
00197     {
00198         ERR("RegOpenKeyExW failed: %d\n", Err);
00199         SetLastError(Err);
00200         return FALSE;
00201     }
00202 
00203     dwSize = sizeof(MACHINE_POWER_POLICY);
00204     Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)pmachinePwrPolicy, &dwSize);
00205     
00206     if (Err != ERROR_SUCCESS)
00207     {
00208         ERR("RegQueryValueExW failed: %d\n", Err);
00209         SetLastError(Err);
00210         RegCloseKey(hKey);
00211         return FALSE;
00212     }
00213 
00214     RegCloseKey(hKey);
00215 
00216     return TRUE;
00217 }
00218 
00219 BOOLEAN WINAPI
00220 EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc,
00221                LPARAM lParam)
00222 {
00223     HKEY hKey;
00224     LONG Err;
00225     DWORD dwSize, dwNameSize = MAX_PATH, dwDescSize = MAX_PATH, dwIndex = 0;
00226     WCHAR szNum[3 + 1], szName[MAX_PATH], szDesc[MAX_PATH];
00227     POWER_POLICY PwrPolicy;
00228     USER_POWER_POLICY userPwrPolicy;
00229     MACHINE_POWER_POLICY machinePwrPolicy;
00230     BOOLEAN bRet = FALSE;
00231 
00232     if (!lpfnPwrSchemesEnumProc)
00233     {
00234         SetLastError(ERROR_INVALID_PARAMETER);
00235         return FALSE;
00236     }
00237 
00238     Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\PowerPolicies", 0, KEY_READ, &hKey);
00239     if (Err != ERROR_SUCCESS)
00240     {
00241         ERR("RegOpenKeyW failed: %d\n", Err);
00242         SetLastError(Err);
00243         return FALSE;
00244     }
00245 
00246     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00247 
00248     dwSize = sizeof(szNum) / sizeof(WCHAR);
00249 
00250     while (RegEnumKeyExW(hKey, dwIndex, szNum, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
00251     {
00252         if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy,
00253                                          dwNameSize, szName,
00254                                          dwDescSize, szDesc))
00255         {
00256             WARN("POWRPROF_GetUserPowerPolicy failed\n");
00257             goto cleanup;
00258         }
00259 
00260         if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy))
00261         {
00262             WARN("POWRPROF_GetMachinePowerPolicy failed\n");
00263             goto cleanup;
00264         }
00265 
00266         memcpy(&PwrPolicy.user, &userPwrPolicy, sizeof(USER_POWER_POLICY));
00267         memcpy(&PwrPolicy.mach, &machinePwrPolicy, sizeof(MACHINE_POWER_POLICY));
00268 
00269         if (!lpfnPwrSchemesEnumProc(_wtoi(szNum), dwNameSize, szName, dwDescSize, szDesc, &PwrPolicy, lParam))
00270             goto cleanup;
00271         else
00272             bRet = TRUE;
00273 
00274         dwSize = sizeof(szNum) / sizeof(WCHAR);
00275         dwIndex++;
00276     }
00277 
00278 cleanup:
00279     RegCloseKey(hKey);
00280     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00281 
00282     return bRet;
00283 }
00284 
00285 BOOLEAN WINAPI
00286 GetActivePwrScheme(PUINT puiID)
00287 {
00288     HKEY hKey;
00289     WCHAR szBuf[MAX_PATH];
00290     DWORD dwSize;
00291     LONG Err;
00292 
00293     TRACE("GetActivePwrScheme(%u)", puiID);
00294 
00295     Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg", 0, KEY_READ, &hKey);
00296     if (Err != ERROR_SUCCESS)
00297     {
00298         ERR("RegOpenKey failed: %d\n", Err);
00299         SetLastError(Err);
00300         return FALSE;
00301     }
00302 
00303     dwSize = MAX_PATH;
00304     Err = RegQueryValueExW(hKey, L"CurrentPowerPolicy",
00305                            NULL, NULL,
00306                            (LPBYTE)&szBuf, &dwSize);
00307     if (Err != ERROR_SUCCESS)
00308     {
00309         ERR("RegQueryValueEx failed: %d\n", Err);
00310         RegCloseKey(hKey);
00311         SetLastError(Err);
00312         return FALSE;
00313     }
00314 
00315     RegCloseKey(hKey);
00316     *puiID = _wtoi(szBuf);
00317 
00318     return TRUE;
00319 }
00320 
00321 BOOLEAN WINAPI
00322 GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pGlobalPowerPolicy,
00323                         PPOWER_POLICY pPowerPolicy)
00324 {
00325     /*
00326     SYSTEM_POWER_POLICY ACPower, DCPower;
00327 
00328     FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy, pPowerPolicy);
00329 
00330     NtPowerInformation(SystemPowerPolicyAc, 0, 0, &ACPower, sizeof(SYSTEM_POWER_POLICY));
00331     NtPowerInformation(SystemPowerPolicyDc, 0, 0, &DCPower, sizeof(SYSTEM_POWER_POLICY));
00332 
00333     return FALSE;
00334     */
00335 /*
00336    Lohnegrim: I dont know why this Function shoud call NtPowerInformation, becouse as far as i know,
00337       it simply returns the GlobalPowerPolicy and the AktivPowerScheme!
00338  */
00339     UINT uiID;
00340 
00341     if (pGlobalPowerPolicy != NULL)
00342     {
00343         if (!ReadGlobalPwrPolicy(pGlobalPowerPolicy))
00344             return FALSE;
00345     }
00346     if (pPowerPolicy != NULL)
00347     {
00348         if (!GetActivePwrScheme(&uiID))
00349             return FALSE;
00350 
00351         if (!ReadPwrScheme(uiID, pPowerPolicy))
00352             return FALSE;
00353     }
00354 
00355     return TRUE;
00356 }
00357 
00358 BOOLEAN WINAPI
00359 GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities)
00360 {
00361     NTSTATUS Status;
00362 
00363     TRACE("(%p)\n", lpSystemPowerCapabilities);
00364 
00365     if (!lpSystemPowerCapabilities)
00366     {
00367         SetLastError(ERROR_INVALID_PARAMETER);
00368         return FALSE;
00369     }
00370 
00371     Status = NtPowerInformation(SystemPowerCapabilities, 0, 0, lpSystemPowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES));
00372     if(!NT_SUCCESS(Status))
00373     {
00374         SetLastError(RtlNtStatusToDosError(Status));
00375         return FALSE;
00376     }
00377 
00378     return TRUE;
00379 }
00380 
00381 BOOLEAN WINAPI
00382 GetPwrDiskSpindownRange(PUINT RangeMax, PUINT RangeMin)
00383 {
00384     HKEY hKey;
00385     BYTE lpValue[40];
00386     LONG Ret;
00387     DWORD cbValue = sizeof(lpValue);
00388 
00389     TRACE("(%p, %p)\n", RangeMax, RangeMin);
00390 
00391     if (RangeMax == NULL || RangeMin == NULL)
00392     {
00393         SetLastError(ERROR_INVALID_PARAMETER);
00394         return FALSE;
00395     }
00396 
00397     WaitForSingleObject(PPRegSemaphore, INFINITE);
00398 
00399     Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey);
00400     if (Ret != ERROR_SUCCESS)
00401     {
00402         TRACE("RegOpenKeyEx failed: %d\n", Ret);
00403         TRACE("Using defaults: 3600, 3\n");
00404         *RangeMax = 3600;
00405         *RangeMin = 3;
00406         ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00407         return TRUE;
00408     }
00409 
00410     Ret = RegQueryValueExW(hKey, szDiskMax, 0, 0, lpValue, &cbValue);
00411     if (Ret != ERROR_SUCCESS)
00412     {
00413         TRACE("Couldn't open DiskSpinDownMax: %d\n", Ret);
00414         TRACE("Using default: 3600\n");
00415         *RangeMax = 3600;
00416     }
00417     else
00418     {
00419         *RangeMax = _wtoi((LPCWSTR)lpValue);
00420     }
00421 
00422     cbValue = sizeof(lpValue);
00423 
00424     Ret = RegQueryValueExW(hKey, szDiskMin, 0, 0, lpValue, &cbValue);
00425     if (Ret != ERROR_SUCCESS)
00426     {
00427         TRACE("Couldn't open DiskSpinDownMin: %d\n", Ret);
00428         TRACE("Using default: 3\n");
00429         *RangeMin = 3;
00430     }
00431     else
00432     {
00433         *RangeMin = _wtoi((LPCWSTR)lpValue);
00434     }
00435 
00436     RegCloseKey(hKey);
00437 
00438     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00439 
00440     return TRUE;
00441 }
00442 
00443 BOOLEAN WINAPI
00444 IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p)
00445 {
00446     FIXME("( %p) stub!\n", p);
00447     return FALSE;
00448 }
00449 
00450 BOOLEAN WINAPI
00451 IsPwrHibernateAllowed(VOID)
00452 {
00453     SYSTEM_POWER_CAPABILITIES PowerCaps;
00454     NTSTATUS Status;
00455     BOOLEAN old;
00456 
00457     RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
00458 
00459     Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
00460     if (!NT_SUCCESS(Status))
00461     {
00462         SetLastError(RtlNtStatusToDosError(Status));
00463         return FALSE;
00464     }
00465 
00466     return PowerCaps.SystemS4 && PowerCaps.HiberFilePresent; // IsHiberfilPresent();
00467 }
00468 
00469 BOOLEAN WINAPI
00470 IsPwrShutdownAllowed(VOID)
00471 {
00472     SYSTEM_POWER_CAPABILITIES PowerCaps;
00473     NTSTATUS Status;
00474     BOOLEAN old;
00475 
00476     RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
00477 
00478     Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
00479     if (!NT_SUCCESS(Status))
00480     {
00481         SetLastError(RtlNtStatusToDosError(Status));
00482         return FALSE;
00483     }
00484 
00485     return PowerCaps.SystemS5;
00486 }
00487 
00488 BOOLEAN WINAPI
00489 IsPwrSuspendAllowed(VOID)
00490 {
00491     SYSTEM_POWER_CAPABILITIES PowerCaps;
00492     NTSTATUS Status;
00493     BOOLEAN old;
00494 
00495     RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
00496 
00497     Status = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
00498     if (!NT_SUCCESS(Status))
00499     {
00500         SetLastError(RtlNtStatusToDosError(Status));
00501         return FALSE;
00502     }
00503 
00504     return PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3;
00505 }
00506 
00507 DWORD WINAPI
00508 PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid)
00509 {
00510    FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid);
00511    return ERROR_CALL_NOT_IMPLEMENTED;
00512 }
00513 
00514 DWORD WINAPI
00515 PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize)
00516 {
00517    FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Type, Buffer, BufferSize);
00518    return ERROR_CALL_NOT_IMPLEMENTED;
00519 }
00520 
00521 BOOLEAN WINAPI
00522 ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)
00523 {
00524     GLOBAL_MACHINE_POWER_POLICY glMachPwrPolicy;
00525     GLOBAL_USER_POWER_POLICY glUserPwrPolicy;
00526     HKEY hKey = NULL;
00527     DWORD dwSize;
00528     LONG Err;
00529     BOOL bRet = FALSE;
00530 
00531     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00532 
00533     // Getting user global power policy
00534     Err = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey);
00535     if (Err != ERROR_SUCCESS)
00536     {
00537         ERR("RegOpenKeyW failed: %d\n", Err);
00538         SetLastError(Err);
00539         goto cleanup;
00540     }
00541 
00542     dwSize = sizeof(glUserPwrPolicy);
00543     Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glUserPwrPolicy, &dwSize);
00544     if (Err != ERROR_SUCCESS)
00545     {
00546         ERR("RegQueryValueExW failed: %d\n", Err);
00547         SetLastError(Err);
00548         goto cleanup;
00549     }
00550 
00551     RegCloseKey(hKey);
00552 
00553     // Getting machine global power policy
00554     Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy", 0, KEY_READ, &hKey);
00555     if (Err != ERROR_SUCCESS)
00556     {
00557         ERR("RegOpenKeyW failed: %d\n", Err);
00558         SetLastError(Err);
00559         goto cleanup;
00560     }
00561 
00562     dwSize = sizeof(glMachPwrPolicy);
00563     Err = RegQueryValueExW(hKey, L"Policies", NULL, NULL, (LPBYTE)&glMachPwrPolicy, &dwSize);
00564     if (Err != ERROR_SUCCESS)
00565     {
00566         ERR("RegQueryValueExW failed: %d\n", Err);
00567         SetLastError(Err);
00568         goto cleanup;
00569     }
00570 
00571     memcpy(&pGlobalPowerPolicy->user, &glUserPwrPolicy, sizeof(GLOBAL_USER_POWER_POLICY));
00572     memcpy(&pGlobalPowerPolicy->mach, &glMachPwrPolicy, sizeof(GLOBAL_MACHINE_POWER_POLICY));
00573     bRet = TRUE;
00574 
00575 cleanup:
00576     if(hKey)
00577         RegCloseKey(hKey);
00578     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00579 
00580     return bRet;
00581 }
00582 
00583 
00584 BOOLEAN WINAPI
00585 ReadProcessorPwrScheme(UINT uiID,
00586                        PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
00587 {
00588     HKEY hKey;
00589     WCHAR szPath[MAX_PATH];
00590     DWORD dwSize = sizeof(MACHINE_PROCESSOR_POWER_POLICY);
00591 
00592     swprintf(szPath, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", uiID);
00593     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
00594         return FALSE;
00595 
00596     if (RegQueryValueExW(hKey, szPolicies, NULL, 0, (LPBYTE)pMachineProcessorPowerPolicy, &dwSize) == ERROR_SUCCESS)
00597     {
00598         RegCloseKey(hKey);
00599         return TRUE;
00600     }
00601 
00602     RegCloseKey(hKey);
00603     if (uiID != 0)
00604         return ReadProcessorPwrScheme(0, pMachineProcessorPowerPolicy);
00605 
00606     return FALSE;
00607 }
00608 
00609 
00610 BOOLEAN WINAPI
00611 ReadPwrScheme(UINT uiID,
00612     PPOWER_POLICY pPowerPolicy)
00613 {
00614     USER_POWER_POLICY userPwrPolicy;
00615     MACHINE_POWER_POLICY machinePwrPolicy;
00616     WCHAR szNum[16]; // max number - 999
00617 
00618     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00619 
00620     swprintf(szNum, L"%d", uiID);
00621 
00622     if (!POWRPROF_GetUserPowerPolicy(szNum, &userPwrPolicy, 0, NULL, 0, NULL))
00623     {
00624         ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00625         return FALSE;
00626     }
00627 
00628     if (!POWRPROF_GetMachinePowerPolicy(szNum, &machinePwrPolicy))
00629     {
00630         ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00631         return FALSE;
00632     }
00633 
00634     memcpy(&pPowerPolicy->user, &userPwrPolicy, sizeof(userPwrPolicy));
00635     memcpy(&pPowerPolicy->mach, &machinePwrPolicy, sizeof(machinePwrPolicy));
00636 
00637     ReleaseSemaphore(PPRegSemaphore, 1, NULL);
00638 
00639     return TRUE;
00640 }
00641 
00642 BOOLEAN WINAPI
00643 SetActivePwrScheme(UINT uiID,
00644                    PGLOBAL_POWER_POLICY lpGlobalPowerPolicy,
00645                    PPOWER_POLICY lpPowerPolicy)
00646 {
00647     POWER_POLICY tmp;
00648     HKEY hKey;
00649     WCHAR Buf[16];
00650 
00651     if (!ReadPwrScheme(uiID, &tmp))
00652         return FALSE;
00653 
00654     if (RegOpenKeyEx(HKEY_CURRENT_USER, szUserPowerConfigSubKey, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
00655         return FALSE;
00656 
00657     swprintf(Buf, L"%i", uiID);
00658 
00659     if (RegSetValueExW(hKey, szCurrentPowerPolicies, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR)) != ERROR_SUCCESS)
00660     {
00661         RegCloseKey(hKey);
00662         return FALSE;
00663     }
00664     RegCloseKey(hKey);
00665 
00666     if (lpGlobalPowerPolicy != NULL || lpPowerPolicy != NULL)
00667     {
00668         if (!ValidatePowerPolicies(lpGlobalPowerPolicy, lpPowerPolicy))
00669             return FALSE;
00670 
00671         if (lpGlobalPowerPolicy != NULL && !WriteGlobalPwrPolicy(lpGlobalPowerPolicy))
00672             return FALSE;
00673 
00674         if (lpPowerPolicy != NULL && !WritePwrPolicy(&uiID,lpPowerPolicy))
00675             return FALSE;
00676     }
00677 
00678     return TRUE;
00679 }
00680 
00681 BOOLEAN WINAPI
00682 SetSuspendState(BOOLEAN Hibernate,
00683                 BOOLEAN ForceCritical,
00684                 BOOLEAN DisableWakeEvent)
00685 {
00686     FIXME("(%d, %d, %d) stub!\n", Hibernate, ForceCritical, DisableWakeEvent);
00687     return TRUE;
00688 }
00689 
00690 BOOLEAN WINAPI
00691 WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy)
00692 {
00693     HKEY hKey;
00694     GLOBAL_USER_POWER_POLICY gupp;
00695     GLOBAL_MACHINE_POWER_POLICY gmpp;
00696 
00697     gupp = pGlobalPowerPolicy->user;
00698     gmpp = pGlobalPowerPolicy->mach;
00699 
00700     if (RegOpenKeyEx(HKEY_CURRENT_USER,
00701                     L"Control Panel\\PowerCfg\\GlobalPowerPolicy",
00702                     0,
00703                     KEY_WRITE,
00704                     &hKey) != ERROR_SUCCESS)
00705         return FALSE;
00706 
00707     if (RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)&gupp, sizeof(gupp)) != ERROR_SUCCESS)
00708     {
00709         RegCloseKey(hKey);
00710         return FALSE;
00711     }
00712 
00713     RegCloseKey(hKey);
00714 
00715     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00716                      L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\GlobalPowerPolicy",
00717                      0,
00718                      KEY_ALL_ACCESS,
00719                      &hKey))
00720         return FALSE;
00721 
00722     if (RegSetValueExW(hKey,szPolicies, 0, REG_BINARY, (PBYTE)&gmpp, sizeof(gmpp)) != ERROR_SUCCESS)
00723     {
00724         RegCloseKey(hKey);
00725         return FALSE;
00726     }
00727 
00728     RegCloseKey(hKey);
00729     return TRUE;
00730 }
00731 
00732 BOOLEAN WINAPI
00733 WriteProcessorPwrScheme(UINT ID,
00734                         PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy)
00735 {
00736     WCHAR Buf[MAX_PATH];
00737     HKEY hKey;
00738     
00739     swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\ProcessorPolicies\\%i", ID);
00740 
00741     if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS)
00742         return FALSE;
00743 
00744     RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (PBYTE)pMachineProcessorPowerPolicy, sizeof(MACHINE_PROCESSOR_POWER_POLICY));
00745     RegCloseKey(hKey);
00746     return TRUE;
00747 }
00748 
00749 static VOID
00750 SetLastID(VOID)
00751 {
00752     WCHAR Buf[16];
00753     HKEY hKey;
00754 
00755     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00756                     szPowerCfgSubKey,
00757                     0,
00758                     KEY_WRITE,
00759                     &hKey) != ERROR_SUCCESS)
00760         return;
00761     swprintf(Buf, L"%i", g_LastID);
00762     RegSetValueExW(hKey, szLastID, 0, REG_SZ, (PBYTE)Buf, strlenW(Buf)*sizeof(WCHAR));
00763     RegCloseKey(hKey);
00764 }
00765 
00766 BOOLEAN WINAPI
00767 WritePwrScheme(PUINT puiID,
00768                LPWSTR lpszName,
00769                LPWSTR lpszDescription,
00770                PPOWER_POLICY pPowerPolicy)
00771 {
00772     WCHAR Buf[MAX_PATH];
00773     HKEY hKey;
00774 
00775     if (*puiID == -1)
00776     {
00777         g_LastID++;
00778         *puiID = g_LastID;
00779         SetLastID();
00780     }
00781 
00782     swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID);
00783 
00784     if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS)
00785         return FALSE;
00786 
00787     RegSetValueExW(hKey, szName, 0, REG_SZ, (PBYTE)lpszName, strlenW(lpszName)*sizeof(WCHAR));
00788     RegSetValueExW(hKey, szDescription, 0, REG_SZ, (PBYTE)lpszDescription, strlenW(lpszDescription)*sizeof(WCHAR));
00789     RegCloseKey(hKey);
00790     return WritePwrPolicy(puiID, pPowerPolicy);
00791 }
00792 
00793 static BOOLEAN
00794 CheckPowerActionPolicy(PPOWER_ACTION_POLICY pPAP, SYSTEM_POWER_CAPABILITIES PowerCaps)
00795 {
00796 /*
00797    Lohnegrim: this is an Helperfunction, it checks if the POWERACTIONPOLICY is valid
00798    Also, if the System dosn't support Hipernation, then change the PowerAction
00799 */
00800     switch (pPAP->Action)
00801     {
00802     case PowerActionNone:
00803         return TRUE;
00804     case PowerActionReserved:
00805         if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3)
00806             pPAP->Action = PowerActionSleep;
00807         else
00808             pPAP->Action = PowerActionReserved;
00809     case PowerActionSleep:
00810         return TRUE;
00811     case PowerActionHibernate:
00812         if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent))
00813         {
00814             if (PowerCaps.SystemS1 || PowerCaps.SystemS2 || PowerCaps.SystemS3)
00815                 pPAP->Action = PowerActionSleep;
00816             else
00817                 pPAP->Action = PowerActionReserved;
00818         }
00819     case PowerActionShutdown:
00820     case PowerActionShutdownReset:
00821     case PowerActionShutdownOff:
00822     case PowerActionWarmEject:
00823         return TRUE;
00824     default:
00825         SetLastError(ERROR_INVALID_DATA);
00826         return FALSE;
00827     };
00828 }
00829 
00830 static VOID
00831 FixSystemPowerState(PSYSTEM_POWER_STATE Psps, SYSTEM_POWER_CAPABILITIES PowerCaps)
00832 {
00833     //Lohnegrim: If the System dosn't support the Powerstates, then we have to change them
00834     if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1)
00835         *Psps = PowerSystemSleeping2;
00836     if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2)
00837         *Psps = PowerSystemSleeping3;
00838     if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3)
00839         *Psps = PowerSystemHibernate;
00840     if (!(PowerCaps.SystemS4 && PowerCaps.HiberFilePresent) && *Psps == PowerSystemHibernate)
00841         *Psps = PowerSystemSleeping2;
00842     if (!PowerCaps.SystemS1 && *Psps == PowerSystemSleeping1)
00843         *Psps = PowerSystemSleeping2;
00844     if (!PowerCaps.SystemS2 && *Psps == PowerSystemSleeping2)
00845         *Psps = PowerSystemSleeping3;
00846     if (!PowerCaps.SystemS3 && *Psps == PowerSystemSleeping3)
00847         *Psps = PowerSystemShutdown;
00848 
00849 }
00850 
00851 BOOLEAN WINAPI
00852 ValidatePowerPolicies(PGLOBAL_POWER_POLICY pGPP, PPOWER_POLICY pPP)
00853 {
00854     SYSTEM_POWER_CAPABILITIES PowerCaps;
00855     NTSTATUS ret;
00856     BOOLEAN old;
00857 
00858     RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &old);
00859     ret = NtPowerInformation(SystemPowerCapabilities, NULL, 0, &PowerCaps, sizeof(PowerCaps));
00860     if (ret != STATUS_SUCCESS)
00861     {
00862         SetLastError(RtlNtStatusToDosError(ret));
00863         return FALSE;
00864     }
00865 
00866     if (pGPP)
00867     {
00868         if (pGPP->user.Revision != 1 || pGPP->mach.Revision != 1)
00869         {
00870             SetLastError(ERROR_REVISION_MISMATCH);
00871             return FALSE;
00872         }
00873         if (pGPP->mach.LidOpenWakeAc == PowerSystemUnspecified)
00874         {
00875             SetLastError(ERROR_GEN_FAILURE);
00876             return FALSE;
00877         }
00878         if ((int)pGPP->mach.LidOpenWakeAc >= PowerSystemShutdown)
00879         {
00880             SetLastError(ERROR_GEN_FAILURE);
00881             return FALSE;
00882         }
00883         if (pGPP->mach.LidOpenWakeDc < PowerSystemWorking)
00884         {
00885             SetLastError(ERROR_GEN_FAILURE);
00886             return FALSE;
00887         }
00888         if ((int)pGPP->mach.LidOpenWakeDc >= PowerSystemShutdown)
00889         {
00890             SetLastError(ERROR_GEN_FAILURE);
00891             return FALSE;
00892         }
00893         //Lohnegrim: unneeded
00894         /*if ((pGPP->mach.LidOpenWakeDc < PowerSystemWorking) || (pGPP->mach.LidOpenWakeDc >= PowerSystemMaximum))
00895         {
00896             SetLastError(ERROR_GEN_FAILURE);
00897             return FALSE;
00898         }*/
00899         if (!CheckPowerActionPolicy(&pGPP->user.LidCloseAc,PowerCaps))
00900         {
00901             return FALSE;
00902         }
00903         if (!CheckPowerActionPolicy(&pGPP->user.LidCloseDc,PowerCaps))
00904         {
00905             return FALSE;
00906         }
00907         if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonAc,PowerCaps))
00908         {
00909             return FALSE;
00910         }
00911         if (!CheckPowerActionPolicy(&pGPP->user.PowerButtonDc,PowerCaps))
00912         {
00913             return FALSE;
00914         }
00915         if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonAc,PowerCaps))
00916         {
00917             return FALSE;
00918         }
00919         if (!CheckPowerActionPolicy(&pGPP->user.SleepButtonDc,PowerCaps))
00920         {
00921             return FALSE;
00922         }
00923         //Lohnegrim: The BroadcastCapacityResolution presents the Powerlevel in Percent, if invalid set th 100 == FULL
00924         if ((pGPP->mach.BroadcastCapacityResolution < 0) || (pGPP->mach.BroadcastCapacityResolution > 100))
00925             pGPP->mach.BroadcastCapacityResolution=100;
00926 
00927         //Lohnegrim: I have no idear, if they are realy needed, or if they are spezific for my System, or what they mean, so i removed them
00928         //pGPP->user.DischargePolicy[1].PowerPolicy.EventCode = pGPP->user.DischargePolicy[1].PowerPolicy.EventCode | 0x010000;
00929         //pGPP->user.DischargePolicy[2].PowerPolicy.EventCode = pGPP->user.DischargePolicy[2].PowerPolicy.EventCode | 0x020000;
00930         //pGPP->user.DischargePolicy[3].PowerPolicy.EventCode = pGPP->user.DischargePolicy[3].PowerPolicy.EventCode | 0x030000;
00931 
00932         FixSystemPowerState(&pGPP->mach.LidOpenWakeAc,PowerCaps);
00933         FixSystemPowerState(&pGPP->mach.LidOpenWakeDc,PowerCaps);
00934 
00935     }
00936 
00937     if (pPP)
00938     {
00939         if (pPP->user.Revision != 1 || pPP->mach.Revision != 1)
00940         {
00941             SetLastError(ERROR_REVISION_MISMATCH);
00942             return FALSE;
00943         }
00944         
00945         //Lohnegrim: unneeded
00946         //if (pPP->mach.MinSleepAc < PowerSystemWorking)
00947         //{
00948         //    SetLastError(ERROR_GEN_FAILURE);
00949         //    return FALSE;
00950         //}
00951         if ((int)pPP->mach.MinSleepAc >= PowerSystemShutdown)
00952         {
00953             SetLastError(ERROR_GEN_FAILURE);
00954             return FALSE;
00955         }
00956         //Lohnegrim: unneeded
00957         //if (pPP->mach.MinSleepDc < PowerSystemWorking)
00958         //{
00959         //    SetLastError(ERROR_GEN_FAILURE);
00960         //    return FALSE;
00961         //}
00962         if ((int)pPP->mach.MinSleepDc >= PowerSystemShutdown)
00963         {
00964             SetLastError(ERROR_GEN_FAILURE);
00965             return FALSE;
00966         }
00967         if (pPP->mach.ReducedLatencySleepAc == PowerSystemUnspecified)
00968         {
00969             SetLastError(ERROR_GEN_FAILURE);
00970             return FALSE;
00971         }
00972         if ((int)pPP->mach.ReducedLatencySleepAc >= PowerSystemShutdown)
00973         {
00974             SetLastError(ERROR_GEN_FAILURE);
00975             return FALSE;
00976         }
00977         if (pPP->mach.ReducedLatencySleepDc < PowerSystemWorking)
00978         {
00979             SetLastError(ERROR_GEN_FAILURE);
00980             return FALSE;
00981         }
00982         if ((int)pPP->mach.ReducedLatencySleepDc >= PowerSystemShutdown)
00983         {
00984             SetLastError(ERROR_GEN_FAILURE);
00985             return FALSE;
00986         }
00987 
00988         if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledAc,PowerCaps))
00989         {
00990             return FALSE;
00991         }
00992         if (!CheckPowerActionPolicy(&pPP->mach.OverThrottledDc,PowerCaps))
00993         {
00994             return FALSE;
00995         }
00996         if (!CheckPowerActionPolicy(&pPP->user.IdleAc,PowerCaps))
00997         {
00998             return FALSE;
00999         }
01000         if (!CheckPowerActionPolicy(&pPP->user.IdleDc,PowerCaps))
01001         {
01002             return FALSE;
01003         }
01004         if (pPP->user.MaxSleepAc < PowerSystemWorking)
01005         {
01006             SetLastError(ERROR_GEN_FAILURE);
01007             return FALSE;
01008         }
01009         //Lohnegrim: unneeded
01010         /*if ((int)pPP->user.MaxSleepAc > PowerSystemShutdown)
01011         {
01012             SetLastError(ERROR_GEN_FAILURE);
01013             return FALSE;
01014         }*/
01015         if (pPP->user.MaxSleepDc < PowerSystemWorking)
01016         {
01017             SetLastError(ERROR_GEN_FAILURE);
01018             return FALSE;
01019         }
01020         //Lohnegrim: unneeded
01021         /*if ((int)pPP->user.MaxSleepDc >= PowerSystemShutdown)
01022         {
01023             SetLastError(ERROR_GEN_FAILURE);
01024             return FALSE;
01025         }*/
01026         if (PowerCaps.SystemS1)
01027         {
01028             pPP->mach.MinSleepAc=PowerSystemSleeping1;
01029             pPP->mach.MinSleepDc=PowerSystemSleeping1;
01030         }
01031         else if (PowerCaps.SystemS2)
01032         {
01033             pPP->mach.MinSleepAc=PowerSystemSleeping2;
01034             pPP->mach.MinSleepDc=PowerSystemSleeping2;
01035         }
01036         else if (PowerCaps.SystemS3)
01037         {
01038             pPP->mach.MinSleepAc=PowerSystemSleeping3;
01039             pPP->mach.MinSleepDc=PowerSystemSleeping3;
01040         }
01041 
01042         if (PowerCaps.SystemS4)
01043         {
01044             pPP->user.MaxSleepAc=PowerSystemSleeping3;
01045             pPP->user.MaxSleepDc=PowerSystemSleeping3;
01046         }
01047         else if (PowerCaps.SystemS3)
01048         {
01049             pPP->user.MaxSleepAc=PowerSystemSleeping2;
01050             pPP->user.MaxSleepDc=PowerSystemSleeping2;
01051         }
01052         else if (PowerCaps.SystemS1)
01053         {
01054             pPP->user.MaxSleepAc=PowerSystemSleeping1;
01055             pPP->user.MaxSleepDc=PowerSystemSleeping1;
01056         }
01057         //Lohnegrim: I dont know where to get this info from, so i removed it
01058         //pPP->user.OptimizeForPowerAc=TRUE;
01059         //pPP->user.OptimizeForPowerDc=TRUE;
01060 
01061         FixSystemPowerState(&pPP->mach.ReducedLatencySleepAc,PowerCaps);
01062         FixSystemPowerState(&pPP->mach.ReducedLatencySleepDc,PowerCaps);
01063     }
01064 
01065     SetLastError(ERROR_SUCCESS);
01066     return TRUE;
01067 }
01068 
01069 BOOLEAN WINAPI WritePwrPolicy(PUINT puiID, PPOWER_POLICY pPowerPolicy)
01070 {
01071     WCHAR Buf[MAX_PATH];
01072     HKEY hKey;
01073 
01074     swprintf(Buf, L"Control Panel\\PowerCfg\\PowerPolicies\\%i", *puiID);
01075 
01076     if (RegCreateKey(HKEY_CURRENT_USER, Buf, &hKey) != ERROR_SUCCESS)
01077         return FALSE;
01078 
01079     RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->user, sizeof(USER_POWER_POLICY));
01080     RegCloseKey(hKey);
01081 
01082     swprintf(Buf, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg\\PowerPolicies\\%i", *puiID);
01083 
01084     if (RegCreateKey(HKEY_LOCAL_MACHINE, Buf, &hKey) != ERROR_SUCCESS)
01085         return FALSE;
01086 
01087     RegSetValueExW(hKey, szPolicies, 0, REG_BINARY, (const unsigned char *)&pPowerPolicy->mach, sizeof(MACHINE_POWER_POLICY));
01088     RegCloseKey(hKey);
01089 
01090     return TRUE;
01091 }
01092 
01093 BOOL WINAPI
01094 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
01095 {
01096     switch(fdwReason)
01097     {
01098         case DLL_PROCESS_ATTACH:
01099         {
01100             HKEY hKey;
01101             LONG Err;
01102 
01103             DisableThreadLibraryCalls(hinstDLL);
01104 
01105             Err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ, &hKey);
01106 
01107             if (Err != ERROR_SUCCESS)
01108             {
01109                 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey));
01110             }
01111             else
01112             {
01113                 WCHAR lpValue[MAX_PATH];
01114                 DWORD cbValue = sizeof(lpValue);
01115 
01116                 Err = RegQueryValueExW(hKey, szLastID, 0, 0, (BYTE*)lpValue, &cbValue);
01117                 if (Err == ERROR_SUCCESS)
01118                 {
01119                     g_LastID = _wtoi(lpValue);
01120                 }
01121                 else
01122                 {
01123                     TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey));
01124                 }
01125                 RegCloseKey(hKey);
01126             }
01127 
01128             PPRegSemaphore = CreateSemaphoreW(NULL, 1, 1, szSemaphoreName);
01129             if (PPRegSemaphore == NULL)
01130             {
01131                 ERR("Couldn't create Semaphore: %d\n", GetLastError());
01132                 return FALSE;
01133             }
01134             break;
01135         }
01136         case DLL_PROCESS_DETACH:
01137             CloseHandle(PPRegSemaphore);
01138             break;
01139     }
01140     return TRUE;
01141 }

Generated on Sun May 27 2012 04:25:52 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.