Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. MoveWinInitRenameToReg.cpp
  5. Abstract:
  6. This shim hooks ExitWindowsEx as well as waits for DLL_PROCESS_DETACH
  7. and then moves the contents of the [Rename] section of wininit.ini
  8. into the registry via MoveFileEx().
  9. History:
  10. 07/24/2000 t-adams Created
  11. 02/12/2002 mnikkel Modified calls to GetPrivateProfileStringW so default was a
  12. null string, not NULL. Also put in loop for retrieving key values
  13. that increased buffer till value fit instead of using MAX_PATH.
  14. --*/
  15. #include "precomp.h"
  16. #define SIZE_STEP MAX_PATH
  17. IMPLEMENT_SHIM_BEGIN(MoveWinInitRenameToReg)
  18. #include "ShimHookMacro.h"
  19. APIHOOK_ENUM_BEGIN
  20. APIHOOK_ENUM_ENTRY(ExitWindowsEx)
  21. APIHOOK_ENUM_END
  22. /*++
  23. Abstract:
  24. Moves the entries in the Rename section of WinInit.ini into
  25. the registry via MoveFileEx().
  26. --*/
  27. void MoveWinInitRenameToReg(void)
  28. {
  29. LPWSTR szKeys = NULL;
  30. LPWSTR szFrom = NULL;
  31. DWORD dwKeysSize = 0;
  32. LPWSTR pszTo = NULL;
  33. CString csWinInit;
  34. CString csWinInitBak;
  35. // Construct the paths to wininit.ini and wininit.bak
  36. csWinInit.GetWindowsDirectoryW();
  37. csWinInitBak.GetWindowsDirectoryW();
  38. csWinInit.AppendPath(L"\\wininit.ini");
  39. csWinInitBak.AppendPath(L"\\wininit.bak");
  40. // Make sure wininit.ini exists.
  41. if( GetFileAttributesW(csWinInit) != INVALID_FILE_ATTRIBUTES)
  42. {
  43. // Copy wininit.ini to wininit.bak because we will be destroying
  44. // wininit.ini as we read through its keys and can't simply rename
  45. // it to wininit.bak later. If the backup fails we can still continue.
  46. CopyFileW(csWinInit, csWinInitBak, FALSE);
  47. // Read the "key" names.
  48. // Since we can't know how big the list of keys is going to be,
  49. // continue to try to get the list until GetPrivateProfile string
  50. // returns something other than dwKeysSize-2 (indicating too small
  51. // of a buffer).
  52. do
  53. {
  54. if( NULL != szKeys )
  55. {
  56. free(szKeys);
  57. }
  58. dwKeysSize += SIZE_STEP;
  59. szKeys = (LPWSTR) malloc(dwKeysSize * sizeof(WCHAR));
  60. if( NULL == szKeys )
  61. {
  62. goto Exit;
  63. }
  64. }
  65. while(GetPrivateProfileStringW(L"Rename", NULL, L"", szKeys, dwKeysSize, csWinInit)
  66. == dwKeysSize - 2);
  67. // Traverse through the keys. If there are no keys, szKeys will be a null terminator.
  68. // Delete each key after we read it so that if there are multiple "NUL" keys,
  69. // our calls to GetPrivateProfileStringA won't continue to return only the
  70. // first NUL key's associated value.
  71. pszTo = szKeys;
  72. while(*pszTo != NULL)
  73. {
  74. DWORD dwFromSize = 0;
  75. do
  76. {
  77. if( NULL != szFrom )
  78. {
  79. free(szFrom);
  80. }
  81. dwFromSize += SIZE_STEP;
  82. szFrom = (LPWSTR) malloc(dwFromSize * sizeof(WCHAR));
  83. if( NULL == szFrom )
  84. {
  85. goto Exit;
  86. }
  87. }
  88. while(GetPrivateProfileStringW(L"Rename", pszTo, L"", szFrom, MAX_PATH, csWinInit)
  89. == dwKeysSize - 1);
  90. WritePrivateProfileStringW(L"Rename", pszTo, NULL, csWinInit);
  91. // If pszTo is "NUL", then the intention is to delete the szFrom file, so pass
  92. // NULL to MoveFileExA(). If the move fails we still wish to continue.
  93. if( wcscmp(pszTo, L"NUL") == 0 )
  94. {
  95. MoveFileExW(szFrom, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  96. }
  97. else
  98. {
  99. MoveFileExW(szFrom, pszTo, MOVEFILE_DELAY_UNTIL_REBOOT);
  100. }
  101. // Move to the next file (key)
  102. pszTo += wcslen(pszTo) + 1;
  103. }
  104. // delete WinInit.ini
  105. DeleteFileW(csWinInit);
  106. }
  107. Exit:
  108. if( NULL != szKeys )
  109. {
  110. free(szKeys);
  111. }
  112. if( NULL != szFrom )
  113. {
  114. free(szFrom);
  115. }
  116. }
  117. /*++
  118. Abstract:
  119. Hook ExitWindowsEx in case the program resets the machine, keeping
  120. us from receiving the DLL_PROCESS_DETACH message. (Shim originally
  121. written for an uninstall program that caused a reset.)
  122. --*/
  123. BOOL
  124. APIHOOK(ExitWindowsEx)(
  125. UINT uFlags,
  126. DWORD dwReserved)
  127. {
  128. MoveWinInitRenameToReg();
  129. return ORIGINAL_API(ExitWindowsEx)(uFlags, dwReserved);
  130. }
  131. /*++
  132. Register hooked functions
  133. --*/
  134. BOOL
  135. NOTIFY_FUNCTION(
  136. DWORD fdwReason)
  137. {
  138. if (fdwReason == DLL_PROCESS_DETACH)
  139. {
  140. MoveWinInitRenameToReg();
  141. }
  142. return TRUE;
  143. }
  144. HOOK_BEGIN
  145. APIHOOK_ENTRY(USER32.DLL, ExitWindowsEx )
  146. CALL_NOTIFY_FUNCTION
  147. HOOK_END
  148. IMPLEMENT_SHIM_END