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.

260 lines
8.7 KiB

  1. // CSetSystemLocal.cpp : Implementation of CSetSystemLocalApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "SetSystemLocale.h"
  4. #include "CSetSystemLocale.h"
  5. #include "Aclapi.h"
  6. #include "Userenv.h"
  7. const ULONG CMDLINE_LENGTH = MAX_PATH+128;
  8. const TCHAR G_LOCALEFILEPATH [] = TEXT("\\System32\\ServerAppliance\\SetSysLoc.txt");
  9. const TCHAR G_COMMANDLINE [] = TEXT("rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:");
  10. const TCHAR G_LOCALEFILEINFO [] = TEXT("[RegionalSettings]\nSystemLocale=%04s\nUserLocale=%04s");
  11. const TCHAR G_QUOTATION [] = TEXT("\"");
  12. const TCHAR G_MUILANGPENDING_VALUENAME[] = TEXT("MUILanguagePending");
  13. const TCHAR G_MUILANGID_VALUENAME[] = TEXT("MultiUILanguageId");
  14. const TCHAR G_REGSUBKEY_PATH[] = TEXT("Control Panel\\Desktop");
  15. const TCHAR G_DEFAULTUSER_KEYNAME[] = TEXT(".DEFAULT\\Control Panel\\Desktop");
  16. const DWORD MAX_LOCALEID_LENGTH = 8;
  17. STDMETHODIMP SetSystemLocale::SetLocale(BSTR LocalID)
  18. {
  19. BOOL bReturn;
  20. HANDLE hFile;
  21. HANDLE hPriToken = NULL;
  22. HANDLE hCurToken = NULL;
  23. TCHAR pstrLocalInfo[CMDLINE_LENGTH];
  24. TCHAR pstrSystemDir[CMDLINE_LENGTH];
  25. TCHAR pstrCmdLine[CMDLINE_LENGTH];
  26. DWORD dwStrLeng,dwWritedLeng;
  27. HRESULT hr = S_OK;
  28. STARTUPINFO startupInfo;
  29. PROCESS_INFORMATION procInfo;
  30. SATraceString( "SetSystemLocal::SetLocal" );
  31. if (wcslen (LocalID) > MAX_LOCALEID_LENGTH)
  32. {
  33. SATracePrintf ("SetSystemLocale passed invalid parameter:%ws", LocalID);
  34. return (E_INVALIDARG);
  35. }
  36. SetMUILangauge( LocalID );
  37. DWORD dwRetVal = ::GetWindowsDirectory( pstrSystemDir, sizeof(pstrSystemDir)/sizeof (pstrSystemDir [0]));
  38. if (0 == dwRetVal)
  39. {
  40. SATraceFailure ("SetSystemLocale-GetWindowsDirectory", GetLastError ());
  41. return (E_FAIL);
  42. }
  43. ::wcscat( pstrSystemDir, G_LOCALEFILEPATH );
  44. do
  45. {
  46. hFile = ::CreateFile( pstrSystemDir,
  47. GENERIC_ALL | MAXIMUM_ALLOWED,
  48. FILE_SHARE_READ,
  49. NULL,
  50. CREATE_ALWAYS,
  51. FILE_ATTRIBUTE_NORMAL,
  52. NULL );
  53. if( hFile == INVALID_HANDLE_VALUE )
  54. {
  55. SATracePrintf( "CreateFile in SetSystemLocaleOnTaskExecute" );
  56. hr = HRESULT_FROM_WIN32( GetLastError() );
  57. break;
  58. }
  59. swprintf( pstrLocalInfo, G_LOCALEFILEINFO, LocalID, LocalID );
  60. dwStrLeng = wcslen( pstrLocalInfo );
  61. bReturn = ::WriteFile( hFile,
  62. pstrLocalInfo,
  63. sizeof(TCHAR)*dwStrLeng,
  64. &dwWritedLeng,
  65. NULL );
  66. if( !bReturn )
  67. {
  68. SATracePrintf( "WriteFile in SetLocaleExecute" );
  69. hr = HRESULT_FROM_WIN32( GetLastError() );
  70. break;
  71. }
  72. bReturn = OpenThreadToken( ::GetCurrentThread(),
  73. TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY,
  74. TRUE,
  75. &hCurToken );
  76. if( !bReturn )
  77. {
  78. SATracePrintf( "OpenThreadToken in SetLocaleExecute" );
  79. bReturn = OpenProcessToken( ::GetCurrentProcess(),
  80. TOKEN_DUPLICATE | TOKEN_IMPERSONATE,
  81. &hCurToken );
  82. if( !bReturn )
  83. {
  84. SATracePrintf( "OpenProcessToken in SetLocal" );
  85. hr = HRESULT_FROM_WIN32( GetLastError() );
  86. break;
  87. }
  88. }
  89. bReturn = DuplicateToken( hCurToken,
  90. SecurityImpersonation,
  91. &hPriToken );
  92. if( !bReturn )
  93. {
  94. SATracePrintf( "DuplicateToken in SetLocExecute" );
  95. hr = HRESULT_FROM_WIN32( GetLastError() );
  96. break;
  97. }
  98. ::wcscpy( pstrCmdLine, G_COMMANDLINE );
  99. ::wcscat( pstrCmdLine, G_QUOTATION );
  100. ::wcscat( pstrCmdLine, pstrSystemDir );
  101. ::wcscat( pstrCmdLine, G_QUOTATION );
  102. ::ZeroMemory (&startupInfo, sizeof (STARTUPINFO));
  103. startupInfo.cb = sizeof( STARTUPINFO );
  104. //::RevertToSelf();
  105. bReturn = ::CreateProcess( NULL,
  106. pstrCmdLine,
  107. NULL,
  108. NULL,
  109. TRUE,
  110. CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS,
  111. NULL,
  112. NULL,
  113. &startupInfo,
  114. &procInfo );
  115. if( !bReturn )
  116. {
  117. SATracePrintf( "CreateProcess in SetSystemLocaleOnTaskExecute" );
  118. hr = HRESULT_FROM_WIN32( GetLastError() );
  119. }
  120. else
  121. {
  122. if ( !::SetThreadToken( &procInfo.hThread, hPriToken ) )
  123. {
  124. SATracePrintf("SetThreadToken Error %d", GetLastError());
  125. hr = HRESULT_FROM_WIN32( GetLastError() );
  126. break;
  127. }
  128. if ( ( ::ResumeThread( procInfo.hThread ) ) == -1 )
  129. {
  130. SATracePrintf("ResumeThread Error %d", GetLastError());
  131. hr = HRESULT_FROM_WIN32( GetLastError() );
  132. break;
  133. }
  134. SATracePrintf( "Success in SetSystemLocaleOnTaskExecute" );
  135. hr = S_OK;
  136. }
  137. }
  138. while( FALSE );
  139. if( hFile )
  140. {
  141. ::CloseHandle( hFile );
  142. }
  143. if( hPriToken )
  144. {
  145. ::CloseHandle(hPriToken);
  146. }
  147. if( hCurToken )
  148. {
  149. ::CloseHandle( hCurToken );
  150. }
  151. return hr;
  152. }
  153. void SetSystemLocale::SetMUILangauge(BSTR LocalID)
  154. {
  155. HKEY hCurrentUserKey;
  156. HKEY hDefaultUserKey;
  157. long lCurrentUserReturn;
  158. long lDefaultUserReturn;
  159. WCHAR szLocalID[MAX_LOCALEID_LENGTH+1];
  160. DWORD dwDataSize = (wcslen( LocalID ) +1);
  161. if (dwDataSize < MAX_LOCALEID_LENGTH)
  162. {
  163. swprintf(szLocalID,L"%08s",LocalID);
  164. dwDataSize = MAX_LOCALEID_LENGTH;;
  165. }
  166. ::RegCloseKey(HKEY_CURRENT_USER);
  167. lCurrentUserReturn = ::RegOpenKeyEx( HKEY_CURRENT_USER,
  168. G_REGSUBKEY_PATH,
  169. 0,
  170. KEY_SET_VALUE,
  171. &hCurrentUserKey );
  172. if( ERROR_SUCCESS == lCurrentUserReturn )
  173. {
  174. lCurrentUserReturn = ::RegSetValueEx(
  175. hCurrentUserKey,
  176. G_MUILANGPENDING_VALUENAME,
  177. 0,
  178. REG_SZ,
  179. (BYTE*)szLocalID,
  180. dwDataSize * sizeof(TCHAR)
  181. );
  182. if( lCurrentUserReturn != ERROR_SUCCESS )
  183. {
  184. SATracePrintf( "Set current user pending failed" );
  185. }
  186. ::CloseHandle( hCurrentUserKey );
  187. }
  188. else
  189. {
  190. SATracePrintf( "Create current user key failed" );
  191. }
  192. lDefaultUserReturn = ::RegOpenKeyEx( HKEY_USERS,
  193. G_DEFAULTUSER_KEYNAME,
  194. 0,
  195. KEY_SET_VALUE,
  196. &hDefaultUserKey );
  197. if( ERROR_SUCCESS == lDefaultUserReturn )
  198. {
  199. lDefaultUserReturn = ::RegSetValueEx(
  200. hDefaultUserKey,
  201. G_MUILANGPENDING_VALUENAME,
  202. 0,
  203. REG_SZ,
  204. (BYTE*)szLocalID,
  205. dwDataSize * sizeof(TCHAR)
  206. );
  207. if( lDefaultUserReturn != ERROR_SUCCESS )
  208. {
  209. SATracePrintf( "Set current user key failed" );
  210. }
  211. ::CloseHandle( hDefaultUserKey );
  212. }
  213. else
  214. {
  215. SATracePrintf( "Create default user key failed" );
  216. }
  217. return;
  218. }