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.

360 lines
10 KiB

  1. /*
  2. * shared.cpp
  3. *
  4. * History:
  5. * Feb '98: Created.
  6. *
  7. * Copyright (C) Microsoft Corp. 1998
  8. *
  9. * Only place code in here that all dlls will have STATICALLY LINKED to them
  10. */
  11. #include "pch.hxx"
  12. #include <advpub.h>
  13. #define DEFINE_SHARED_STRINGS
  14. #include "shared.h"
  15. #include <migerror.h>
  16. #include <shlwapi.h>
  17. BOOL GetProgramFilesDir(LPSTR pszPrgfDir, DWORD dwSize, DWORD dwVer)
  18. {
  19. HKEY hkey;
  20. DWORD dwType;
  21. *pszPrgfDir = 0;
  22. if (dwVer >= 5)
  23. {
  24. if ( GetEnvironmentVariable( TEXT("ProgramFiles"), pszPrgfDir, dwSize ) )
  25. return TRUE;
  26. }
  27. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegWinCurrVer, 0, KEY_QUERY_VALUE, &hkey))
  28. {
  29. if (dwVer >= 4)
  30. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szProgFilesDir, 0, &dwType, (LPBYTE)pszPrgfDir, &dwSize))
  31. {
  32. char szSysDrv[5] = { 0 };
  33. // combine reg value and systemDrive to get the acurate ProgramFiles dir
  34. if ( GetEnvironmentVariable( TEXT("SystemDrive"), szSysDrv, ARRAYSIZE(szSysDrv) ) &&
  35. szSysDrv[0] )
  36. *pszPrgfDir = szSysDrv[0];
  37. }
  38. RegCloseKey(hkey);
  39. return TRUE;
  40. }
  41. return FALSE;
  42. }
  43. BOOL ReplaceSubString(LPSTR pszOutLine, DWORD cchSize, LPCSTR pszOldLine, LPCSTR pszSubStr, LPCSTR pszSubReplacement )
  44. {
  45. LPSTR lpszStart = NULL;
  46. LPSTR lpszNewLine;
  47. LPCSTR lpszCur;
  48. BOOL bFound = FALSE;
  49. int ilen;
  50. lpszCur = pszOldLine;
  51. lpszNewLine = pszOutLine;
  52. DWORD cchSizeNewLine = cchSize;
  53. while ( lpszStart = StrStrIA( lpszCur, pszSubStr ) )
  54. {
  55. // this module path has the systemroot
  56. ilen = (int) (lpszStart - lpszCur);
  57. if ( ilen )
  58. {
  59. StrCpyN(lpszNewLine, lpszCur, min((ilen + 1), (int)cchSizeNewLine));
  60. lpszNewLine += ilen;
  61. cchSizeNewLine -= ilen;
  62. }
  63. StrCpyN(lpszNewLine, pszSubReplacement, cchSizeNewLine);
  64. lpszCur = lpszStart + lstrlen(pszSubStr);
  65. ilen = lstrlen(pszSubReplacement);
  66. lpszNewLine += ilen;
  67. cchSizeNewLine -= ilen;
  68. bFound = TRUE;
  69. }
  70. StrCpyN(lpszNewLine, lpszCur, cchSizeNewLine);
  71. return bFound;
  72. }
  73. //==========================================================================================
  74. // AddEnvInPath - Ripped from Advpack
  75. //==========================================================================================
  76. BOOL AddEnvInPath(LPCSTR pszOldPath, LPSTR pszNew, DWORD cchSize)
  77. {
  78. static OSVERSIONINFO verinfo;
  79. static BOOL bNeedOSInfo=TRUE;
  80. CHAR szBuf[MAX_PATH], szEnvVar[MAX_PATH];
  81. CHAR szReplaceStr[100];
  82. CHAR szSysDrv[5];
  83. BOOL bFound = FALSE;
  84. // Do we need to check the OS version or is it cached?
  85. if (bNeedOSInfo)
  86. {
  87. bNeedOSInfo = FALSE;
  88. verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  89. if (GetVersionEx(&verinfo) == FALSE)
  90. {
  91. AssertSz(FALSE, "AddEnvInPath: Couldn't obtain OS ver info.");
  92. verinfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
  93. }
  94. }
  95. // Variable substitution is only supported on NT
  96. if(VER_PLATFORM_WIN32_NT != verinfo.dwPlatformId)
  97. goto exit;
  98. // Try to replace USERPROFILE
  99. if ( GetEnvironmentVariable( "UserProfile", szEnvVar, ARRAYSIZE(szEnvVar) ) &&
  100. ReplaceSubString(szBuf, ARRAYSIZE(szBuf), pszOldPath, szEnvVar, "%UserProfile%" ) )
  101. {
  102. bFound = TRUE;
  103. }
  104. // Try to replace the Program Files Dir
  105. else if ( (verinfo.dwMajorVersion >= 5) && GetEnvironmentVariable( "ProgramFiles", szEnvVar, ARRAYSIZE(szEnvVar) ) &&
  106. ReplaceSubString(szBuf, ARRAYSIZE(szBuf), pszOldPath, szEnvVar, "%ProgramFiles%" ) )
  107. {
  108. bFound = TRUE;
  109. }
  110. // replace c:\winnt Windows folder
  111. else if ( GetEnvironmentVariable( "SystemRoot", szEnvVar, ARRAYSIZE(szEnvVar) ) &&
  112. ReplaceSubString(szBuf, ARRAYSIZE(szBuf), pszOldPath, szEnvVar, "%SystemRoot%" ) )
  113. {
  114. bFound = TRUE;
  115. }
  116. // Replace the c: System Drive letter
  117. else if ( GetEnvironmentVariable( "SystemDrive", szSysDrv, ARRAYSIZE(szSysDrv) ) &&
  118. ReplaceSubString(szBuf, ARRAYSIZE(szBuf), pszOldPath, szSysDrv, "%SystemDrive%" ) )
  119. {
  120. bFound = TRUE;
  121. }
  122. exit:
  123. // this way, if caller pass the same location for both params, still OK.
  124. if ( bFound || ( pszNew != pszOldPath ) )
  125. StrCpyN(pszNew, bFound ? szBuf : pszOldPath, cchSize);
  126. return bFound;
  127. }
  128. // --------------------------------------------------------------------------------
  129. // CallRegInstall - Self-Registration Helper
  130. // --------------------------------------------------------------------------------
  131. HRESULT CallRegInstall(HINSTANCE hInstCaller, HINSTANCE hInstRes, LPCSTR pszSection, LPSTR pszExtra)
  132. {
  133. AssertSz(hInstCaller, "[ARGS] CallRegInstall: NULL hInstCaller");
  134. AssertSz(hInstRes, "[ARGS] CallRegInstall: NULL hInstRes");
  135. AssertSz(hInstRes, "[ARGS] CallRegInstall: NULL pszSection");
  136. HRESULT hr = E_FAIL;
  137. HINSTANCE hAdvPack;
  138. REGINSTALL pfnri;
  139. CHAR szDll[MAX_PATH], szDir[MAX_PATH];
  140. int cch;
  141. // 3 to allow for pszExtra
  142. STRENTRY seReg[3];
  143. STRTABLE stReg;
  144. hAdvPack = LoadLibraryA(c_szAdvPackDll);
  145. if (NULL == hAdvPack)
  146. goto exit;
  147. // Get our location
  148. GetModuleFileName(hInstCaller, szDll, ARRAYSIZE(szDll));
  149. // Get Proc Address for registration util
  150. pfnri = (REGINSTALL)GetProcAddress(hAdvPack, achREGINSTALL);
  151. if (NULL == pfnri)
  152. goto exit;
  153. AddEnvInPath(szDll, szDll, ARRAYSIZE(szDll));
  154. // Setup special registration stuff
  155. // Do this instead of relying on _SYS_MOD_PATH which loses spaces under '95
  156. stReg.cEntries = 0;
  157. seReg[stReg.cEntries].pszName = "SYS_MOD_PATH";
  158. seReg[stReg.cEntries].pszValue = szDll;
  159. stReg.cEntries++;
  160. StrCpyN(szDir, szDll, ARRAYSIZE(szDir));
  161. PathRemoveFileSpec(szDir);
  162. seReg[stReg.cEntries].pszName = "SYS_MOD_PATH_DIR";
  163. seReg[stReg.cEntries].pszValue = szDir;
  164. stReg.cEntries++;
  165. // Allow for caller to give us another string to use in the INF
  166. if (pszExtra)
  167. {
  168. seReg[stReg.cEntries].pszName = "SYS_EXTRA";
  169. seReg[stReg.cEntries].pszValue = pszExtra;
  170. stReg.cEntries++;
  171. }
  172. stReg.pse = seReg;
  173. // Call the self-reg routine
  174. hr = pfnri(hInstRes, pszSection, &stReg);
  175. exit:
  176. // Cleanup
  177. SafeFreeLibrary(hAdvPack);
  178. return(hr);
  179. }
  180. //--------------------------------------------------------------------------
  181. // MakeFilePath
  182. //--------------------------------------------------------------------------
  183. HRESULT MakeFilePath(LPCSTR pszDirectory, LPCSTR pszFileName,
  184. LPCSTR pszExtension, LPSTR pszFilePath, ULONG cchMaxFilePath)
  185. {
  186. // Locals
  187. HRESULT hr=S_OK;
  188. DWORD cchDirectory=lstrlen(pszDirectory);
  189. // Trace
  190. TraceCall("MakeFilePath");
  191. // Invalid Args
  192. Assert(pszDirectory && pszFileName && pszExtension && pszFilePath && cchMaxFilePath >= MAX_PATH);
  193. Assert(pszExtension[0] == '\0' || pszExtension[0] == '.');
  194. // Remove for folders
  195. if (cchDirectory + 1 + lstrlen(pszFileName) + lstrlen(pszExtension) >= (INT)cchMaxFilePath)
  196. {
  197. hr = TraceResult(E_FAIL);
  198. goto exit;
  199. }
  200. // Do we need a backslash
  201. if ('\\' != *CharPrev(pszDirectory, pszDirectory + cchDirectory))
  202. {
  203. // Append backslash
  204. SideAssert(wnsprintf(pszFilePath, cchMaxFilePath, "%s\\%s%s", pszDirectory, pszFileName, pszExtension) < (INT)cchMaxFilePath);
  205. }
  206. // Otherwise
  207. else
  208. {
  209. // Append backslash
  210. SideAssert(wnsprintf(pszFilePath, cchMaxFilePath, "%s%s%s", pszDirectory, pszFileName, pszExtension) < (INT)cchMaxFilePath);
  211. }
  212. exit:
  213. // Done
  214. return hr;
  215. }
  216. // --------------------------------------------------------------------------------
  217. // CloseMemoryFile
  218. // --------------------------------------------------------------------------------
  219. HRESULT CloseMemoryFile(LPMEMORYFILE pFile)
  220. {
  221. // Trace
  222. TraceCall("CloseMemoryFile");
  223. // Args
  224. Assert(pFile);
  225. // Close the View
  226. if (pFile->pView)
  227. UnmapViewOfFile(pFile->pView);
  228. // Close the Memory Map
  229. if (pFile->hMemoryMap)
  230. CloseHandle(pFile->hMemoryMap);
  231. // Close the File
  232. if (pFile->hFile)
  233. CloseHandle(pFile->hFile);
  234. // Zero
  235. ZeroMemory(pFile, sizeof(MEMORYFILE));
  236. // Done
  237. return S_OK;
  238. }
  239. //--------------------------------------------------------------------------
  240. // OpenMemoryFile
  241. //--------------------------------------------------------------------------
  242. HRESULT OpenMemoryFile(LPCSTR pszFile, LPMEMORYFILE pFile)
  243. {
  244. // Locals
  245. HRESULT hr=S_OK;
  246. // Tracing
  247. TraceCall("OpenMemoryMappedFile");
  248. // Invalid Arg
  249. Assert(pszFile && pFile);
  250. // Init
  251. ZeroMemory(pFile, sizeof(MEMORYFILE));
  252. // Open the File
  253. pFile->hFile = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
  254. // Failure
  255. if (INVALID_HANDLE_VALUE == pFile->hFile)
  256. {
  257. pFile->hFile = NULL;
  258. if (ERROR_SHARING_VIOLATION == GetLastError())
  259. hr = TraceResult(MIGRATE_E_SHARINGVIOLATION);
  260. else
  261. hr = TraceResult(MIGRATE_E_CANTOPENFILE);
  262. goto exit;
  263. }
  264. // Get the Size
  265. pFile->cbSize = ::GetFileSize(pFile->hFile, NULL);
  266. if (0xFFFFFFFF == pFile->cbSize)
  267. {
  268. hr = TraceResult(MIGRATE_E_CANTGETFILESIZE);
  269. goto exit;
  270. }
  271. // Create the file mapping
  272. pFile->hMemoryMap = CreateFileMapping(pFile->hFile, NULL, PAGE_READWRITE, 0, pFile->cbSize, NULL);
  273. // Failure ?
  274. if (NULL == pFile->hMemoryMap)
  275. {
  276. hr = TraceResult(MIGRATE_E_CANTCREATEFILEMAPPING);
  277. goto exit;
  278. }
  279. // Map a view of the entire file
  280. pFile->pView = MapViewOfFile(pFile->hMemoryMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  281. // Failure
  282. if (NULL == pFile->pView)
  283. {
  284. hr = TraceResult(MIGRATE_E_CANTMAPVIEWOFFILE);
  285. goto exit;
  286. }
  287. exit:
  288. // Cleanup
  289. if (FAILED(hr))
  290. CloseMemoryFile(pFile);
  291. // Done
  292. return hr;
  293. }