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.

458 lines
12 KiB

  1. //--------------------------------------------------------------------------
  2. // Utility.cpp
  3. //--------------------------------------------------------------------------
  4. #include "pch.hxx"
  5. #include "dllmain.h"
  6. #include "utility.h"
  7. #include "database.h"
  8. #include "wrapwide.h"
  9. //--------------------------------------------------------------------------
  10. // CreateSystemHandleName
  11. //--------------------------------------------------------------------------
  12. HRESULT CreateSystemHandleName(LPCWSTR pwszBase, LPCWSTR pwszSpecific,
  13. LPWSTR *ppwszName)
  14. {
  15. // Locals
  16. HRESULT hr=S_OK;
  17. DWORD cchName;
  18. LPWSTR pszT;
  19. // Trace
  20. TraceCall("CreateSystemHandleName");
  21. // Invalid Args
  22. Assert(pwszBase && pwszSpecific && ppwszName);
  23. // Init
  24. *ppwszName = NULL;
  25. // Compute Length
  26. cchName = lstrlenW(pwszBase) + lstrlenW(pwszSpecific) + 15;
  27. // Allocate
  28. IF_NULLEXIT(*ppwszName = AllocateStringW(cchName));
  29. // Setup Arguments
  30. wsprintfWrapW(*ppwszName, cchName, L"%s%s", pwszBase, pwszSpecific);
  31. // Remove backslashes from this string
  32. for (pszT = (*ppwszName); *pszT != L'\0'; pszT++)
  33. {
  34. // Replace Back Slashes
  35. if (*pszT == L'\\')
  36. {
  37. // With _
  38. *pszT = L'_';
  39. }
  40. }
  41. // Lower Case
  42. CharLowerBuffWrapW(*ppwszName, lstrlenW(*ppwszName));
  43. exit:
  44. // Done
  45. return hr;
  46. }
  47. // --------------------------------------------------------------------------------
  48. // DBGetFullPath
  49. // --------------------------------------------------------------------------------
  50. HRESULT DBGetFullPath(LPCWSTR pszFilePath, LPWSTR *ppszFullPath, LPDWORD pcchFilePath)
  51. {
  52. // Locals
  53. HRESULT hr=S_OK;
  54. DWORD cchAllocate;
  55. LPWSTR pszFilePart;
  56. // Trace
  57. TraceCall("DBGetFullPath");
  58. // Set cchFullPath
  59. cchAllocate = max(lstrlenW(pszFilePath), MAX_PATH + MAX_PATH);
  60. // Allocate ppszFullPath
  61. IF_NULLEXIT(*ppszFullPath = AllocateStringW(cchAllocate));
  62. // GetFullPathName
  63. *pcchFilePath = GetFullPathNameWrapW(pszFilePath, cchAllocate, (*ppszFullPath), &pszFilePart);
  64. // Failure
  65. if (*pcchFilePath && *pcchFilePath >= cchAllocate)
  66. {
  67. // Re-allocate
  68. IF_NULLEXIT(*ppszFullPath = AllocateStringW(*pcchFilePath));
  69. // Expand the Path
  70. *pcchFilePath = GetFullPathNameWrapW(pszFilePath, *pcchFilePath, (*ppszFullPath), &pszFilePart);
  71. }
  72. // cch is 0
  73. if (0 == *pcchFilePath)
  74. {
  75. hr = TraceResult(E_FAIL);
  76. goto exit;
  77. }
  78. // Validate
  79. Assert((*ppszFullPath)[(*pcchFilePath)] == L'\0');
  80. exit:
  81. // Done
  82. return(hr);
  83. }
  84. // --------------------------------------------------------------------------------
  85. // CompareTableIndexes
  86. // --------------------------------------------------------------------------------
  87. HRESULT CompareTableIndexes(LPCTABLEINDEX pIndex1, LPCTABLEINDEX pIndex2)
  88. {
  89. // Locals
  90. DWORD i;
  91. // Trace
  92. TraceCall("CompareTableIndexes");
  93. // Different Number of Keys
  94. if (pIndex1->cKeys != pIndex2->cKeys)
  95. return(S_FALSE);
  96. // Loop through the keys
  97. for (i=0; i<pIndex1->cKeys; i++)
  98. {
  99. // Different Column
  100. if (pIndex1->rgKey[i].iColumn != pIndex2->rgKey[i].iColumn)
  101. return(S_FALSE);
  102. // Different Compare Flags
  103. if (pIndex1->rgKey[i].bCompare != pIndex2->rgKey[i].bCompare)
  104. return(S_FALSE);
  105. // Different Compare Bits
  106. if (pIndex1->rgKey[i].dwBits != pIndex2->rgKey[i].dwBits)
  107. return(S_FALSE);
  108. }
  109. // Equal
  110. return(S_OK);
  111. }
  112. //--------------------------------------------------------------------------
  113. // DBOpenFile
  114. //--------------------------------------------------------------------------
  115. HRESULT DBOpenFile(LPCWSTR pszFile, BOOL fNoCreate, BOOL fExclusive,
  116. BOOL *pfNew, HANDLE *phFile)
  117. {
  118. // Locals
  119. HRESULT hr=S_OK;
  120. HANDLE hFile;
  121. DWORD dwShare;
  122. DWORD dwCreate;
  123. // Trace
  124. TraceCall("DBOpenFile");
  125. // Invalid Args
  126. Assert(pszFile && phFile);
  127. // Initialize
  128. *phFile = NULL;
  129. *pfNew = FALSE;
  130. // Set Share Falgs
  131. dwShare = fExclusive ? 0 : FILE_SHARE_READ | FILE_SHARE_WRITE;
  132. // If not fNoCreate, then OPEN_ALWAYS
  133. dwCreate = fNoCreate ? OPEN_EXISTING : OPEN_ALWAYS;
  134. // Do the CreateFile
  135. hFile = CreateFileWrapW(pszFile, GENERIC_READ | GENERIC_WRITE, dwShare, NULL, dwCreate, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
  136. // Failure
  137. if (INVALID_HANDLE_VALUE == hFile)
  138. {
  139. // Return a Good Error
  140. if (ERROR_SHARING_VIOLATION == GetLastError())
  141. {
  142. // Set hr
  143. hr = TraceResult(DB_E_ACCESSDENIED);
  144. }
  145. // Otherwise, generic Error
  146. else
  147. {
  148. // Create File
  149. hr = TraceResult(DB_E_CREATEFILE);
  150. }
  151. // Done
  152. goto exit;
  153. }
  154. // If Not no create
  155. if (FALSE == fNoCreate)
  156. {
  157. // Return pfNew ?
  158. *pfNew = (ERROR_ALREADY_EXISTS == GetLastError()) ? FALSE : TRUE;
  159. }
  160. // Return the hFile
  161. *phFile = hFile;
  162. exit:
  163. // Done
  164. return(hr);
  165. }
  166. //--------------------------------------------------------------------------
  167. // DBMapViewOfFile
  168. //--------------------------------------------------------------------------
  169. HRESULT DBMapViewOfFile(HANDLE hMapping, DWORD cbFile, LPFILEADDRESS pfaView,
  170. LPDWORD pcbView, LPVOID *ppvView)
  171. {
  172. // Locals
  173. FILEADDRESS faBase = (*pfaView);
  174. DWORD cbSize = (*pcbView);
  175. // cbBoundary
  176. DWORD cbBoundary = (faBase % g_SystemInfo.dwAllocationGranularity);
  177. // Decrement faBase
  178. faBase -= cbBoundary;
  179. // Increment cbSize
  180. cbSize += cbBoundary;
  181. // Fixup cbSize
  182. if (faBase + cbSize > cbFile)
  183. {
  184. // Map to the end of the file
  185. cbSize = (cbFile - faBase);
  186. }
  187. // Map a view of the entire file
  188. *ppvView = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, faBase, cbSize);
  189. // Failure
  190. if (NULL == *ppvView)
  191. return(TraceResult(DB_E_MAPVIEWOFFILE));
  192. // Return Actual Sizes
  193. *pfaView = faBase;
  194. *pcbView = cbSize;
  195. // Success
  196. return(S_OK);
  197. }
  198. //--------------------------------------------------------------------------
  199. // DBOpenFileMapping
  200. //--------------------------------------------------------------------------
  201. HRESULT DBOpenFileMapping(HANDLE hFile, LPCWSTR pwszName, DWORD cbSize, BOOL *pfNew,
  202. HANDLE *phMemoryMap, LPVOID *ppvView)
  203. {
  204. // Locals
  205. HRESULT hr=S_OK;
  206. HANDLE hMemoryMap=NULL;
  207. LPVOID pvView=NULL;
  208. // Tracing
  209. TraceCall("OpenFileMapping");
  210. // Invalid Arg
  211. Assert(hFile != NULL && phMemoryMap && pfNew);
  212. // Initialize
  213. *phMemoryMap = NULL;
  214. *pfNew = FALSE;
  215. if (ppvView)
  216. *ppvView = NULL;
  217. // Open or create the file mapping
  218. hMemoryMap = OpenFileMappingWrapW(FILE_MAP_ALL_ACCESS, FALSE, pwszName);
  219. // If that failed, then lets create the file mapping
  220. if (NULL == hMemoryMap)
  221. {
  222. // Create the file mapping
  223. hMemoryMap = CreateFileMappingWrapW(hFile, NULL, PAGE_READWRITE, 0, cbSize, pwszName);
  224. // Failure
  225. if (NULL == hMemoryMap)
  226. {
  227. hr = TraceResult(DB_E_CREATEFILEMAPPING);
  228. goto exit;
  229. }
  230. // Set a State
  231. *pfNew = TRUE;
  232. }
  233. // Map the View
  234. if (ppvView)
  235. {
  236. // Map a view of the entire file
  237. pvView = MapViewOfFile(hMemoryMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  238. // Failure
  239. if (NULL == pvView)
  240. {
  241. hr = TraceResult(DB_E_MAPVIEWOFFILE);
  242. goto exit;
  243. }
  244. // Return It
  245. *ppvView = pvView;
  246. // Don't Free It
  247. pvView = NULL;
  248. }
  249. // Set Return Values
  250. *phMemoryMap = hMemoryMap;
  251. // Don't Free
  252. hMemoryMap = NULL;
  253. exit:
  254. // Cleanup
  255. if (pvView)
  256. UnmapViewOfFile(pvView);
  257. if (hMemoryMap)
  258. CloseHandle(hMemoryMap);
  259. // Done
  260. return hr;
  261. }
  262. //--------------------------------------------------------------------------
  263. // RegisterWindowClass
  264. //--------------------------------------------------------------------------
  265. HRESULT RegisterWindowClass(LPCSTR pszClass, WNDPROC pfnWndProc)
  266. {
  267. // Locals
  268. HRESULT hr=S_OK;
  269. WNDCLASS WindowClass;
  270. // Tracing
  271. TraceCall("RegisterWindowClass");
  272. // Register the Window Class
  273. if (0 != GetClassInfo(g_hInst, pszClass, &WindowClass))
  274. goto exit;
  275. // Zero the object
  276. ZeroMemory(&WindowClass, sizeof(WNDCLASS));
  277. // Initialize the Window Class
  278. WindowClass.lpfnWndProc = pfnWndProc;
  279. WindowClass.hInstance = g_hInst;
  280. WindowClass.lpszClassName = pszClass;
  281. // Register the Class
  282. if (0 == RegisterClass(&WindowClass))
  283. {
  284. hr = TraceResult(E_FAIL);
  285. goto exit;
  286. }
  287. exit:
  288. // Done
  289. return hr;
  290. }
  291. //--------------------------------------------------------------------------
  292. // CreateNotifyWindow
  293. //--------------------------------------------------------------------------
  294. HRESULT CreateNotifyWindow(LPCSTR pszClass, LPVOID pvParam, HWND *phwndNotify)
  295. {
  296. // Locals
  297. HRESULT hr=S_OK;
  298. HWND hwnd;
  299. // Tracing
  300. TraceCall("CreateNotifyWindow");
  301. // Invalid ARg
  302. Assert(pszClass && phwndNotify);
  303. // Initialize
  304. *phwndNotify = NULL;
  305. // Create the Window
  306. hwnd = CreateWindowEx(WS_EX_TOPMOST, pszClass, pszClass, WS_POPUP, 0, 0, 0, 0, NULL, NULL, g_hInst, (LPVOID)pvParam);
  307. // Failure
  308. if (NULL == hwnd)
  309. {
  310. hr = TraceResult(E_FAIL);
  311. goto exit;
  312. }
  313. // Set Return
  314. *phwndNotify = hwnd;
  315. exit:
  316. // Done
  317. return hr;
  318. }
  319. //--------------------------------------------------------------------------
  320. // DBGetFileSize
  321. //--------------------------------------------------------------------------
  322. HRESULT DBGetFileSize(HANDLE hFile, LPDWORD pcbSize)
  323. {
  324. // Trace
  325. TraceCall("GetFileSize");
  326. // Invalid Arg
  327. Assert(pcbSize);
  328. // Get the Size
  329. *pcbSize = ::GetFileSize(hFile, NULL);
  330. if (0xFFFFFFFF == *pcbSize)
  331. return TraceResult(DB_E_GETFILESIZE);
  332. // Done
  333. return S_OK;
  334. }
  335. // --------------------------------------------------------------------------------
  336. // GetAvailableDiskSpace
  337. // --------------------------------------------------------------------------------
  338. HRESULT GetAvailableDiskSpace(LPCWSTR pszFilePath, DWORDLONG *pdwlFree)
  339. {
  340. // Locals
  341. HRESULT hr=S_OK;
  342. WCHAR wszDrive[5];
  343. DWORD dwSectorsPerCluster;
  344. DWORD dwBytesPerSector;
  345. DWORD dwNumberOfFreeClusters;
  346. DWORD dwTotalNumberOfClusters;
  347. // Trace
  348. TraceCall("GetAvailableDiskSpace");
  349. // Invalid Args
  350. Assert(pszFilePath && pszFilePath[1] == L':' && pdwlFree);
  351. // Split the path
  352. wszDrive[0] = *pszFilePath;
  353. wszDrive[1] = L':';
  354. wszDrive[2] = L'\\';
  355. wszDrive[3] = L'\0';
  356. // Get free disk space - if it fails, lets pray we have enought disk space
  357. if (!GetDiskFreeSpaceWrapW(wszDrive, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters))
  358. {
  359. hr = TraceResult(E_FAIL);
  360. goto exit;
  361. }
  362. // Return Amount of Free Disk Space
  363. *pdwlFree = (dwNumberOfFreeClusters * (dwSectorsPerCluster * dwBytesPerSector));
  364. exit:
  365. // Done
  366. return hr;
  367. }