Source code of Windows XP (NT5)
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.

343 lines
8.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C B A S E . C P P
  7. //
  8. // Contents: Basic common code.
  9. //
  10. // Notes: Pollute this under penalty of death.
  11. //
  12. // Author: shaunco 20 Sep 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "ncbase.h"
  18. #include "ncdebug.h"
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: AddRefObj
  22. //
  23. // Purpose: AddRef's the object pointed to by punk by calling
  24. // punk->AddRef();
  25. //
  26. // Arguments:
  27. // punk [in] Object to be AddRef'd. Can be NULL.
  28. //
  29. // Returns: Result of AddRef call.
  30. //
  31. // Author: danielwe 25 Feb 1997
  32. //
  33. // Notes: Using this function to AddRef an object will reduce
  34. // our code size.
  35. //
  36. NOTHROW
  37. ULONG
  38. AddRefObj (
  39. IUnknown* punk)
  40. {
  41. return (punk) ? punk->AddRef () : 0;
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Function: ReleaseObj
  46. //
  47. // Purpose: Releases the object pointed to by punk by calling
  48. // punk->Release();
  49. //
  50. // Arguments:
  51. // punk [in] Object to be released. Can be NULL.
  52. //
  53. // Returns: Result of Release call.
  54. //
  55. // Author: danielwe 25 Feb 1997
  56. //
  57. // Notes: Using this function to release a (possibly NULL) object will
  58. // reduce our code size.
  59. //
  60. NOTHROW
  61. ULONG
  62. ReleaseObj (
  63. IUnknown* punk)
  64. {
  65. return (punk) ? punk->Release () : 0;
  66. }
  67. //+--------------------------------------------------------------------------
  68. //
  69. // Function: DwWin32ErrorFromHr
  70. //
  71. // Purpose: Converts the HRESULT to a Win32 error or SetupApi error.
  72. //
  73. // Arguments:
  74. // hr [in] The HRESULT to convert
  75. //
  76. // Returns: Converted DWORD value.
  77. //
  78. // Author: billbe 22 Apr 1997
  79. //
  80. // Notes:
  81. //
  82. NOTHROW
  83. DWORD
  84. DwWin32ErrorFromHr (
  85. HRESULT hr)
  86. {
  87. DWORD dw = ERROR_SUCCESS;
  88. // All success codes convert to ERROR_SUCCESS so we only need to handle
  89. // failures.
  90. if (FAILED(hr))
  91. {
  92. DWORD dwFacility = HRESULT_FACILITY(hr);
  93. if (FACILITY_WIN32 == dwFacility)
  94. {
  95. dw = HRESULT_CODE(hr);
  96. }
  97. else if (FACILITY_ITF == dwFacility)
  98. {
  99. dw = ERROR_GEN_FAILURE;
  100. }
  101. else
  102. {
  103. // cannot convert it
  104. dw = hr;
  105. }
  106. }
  107. return dw;
  108. }
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Function: HrFromLastWin32Error
  112. //
  113. // Purpose: Converts the GetLastError() Win32 call into a proper HRESULT.
  114. //
  115. // Arguments:
  116. // (none)
  117. //
  118. // Returns: Converted HRESULT value.
  119. //
  120. // Author: danielwe 24 Mar 1997
  121. //
  122. // Notes: This is not inline as it actually generates quite a bit of
  123. // code.
  124. // If GetLastError returns an error that looks like a SetupApi
  125. // error, this function will convert the error to an HRESULT
  126. // with FACILITY_SETUP instead of FACILITY_WIN32
  127. //
  128. NOTHROW
  129. HRESULT
  130. HrFromLastWin32Error ()
  131. {
  132. DWORD dwError = GetLastError();
  133. HRESULT hr;
  134. // This test is testing SetupApi errors only (this is
  135. // temporary because the new HRESULT_FROM_SETUPAPI macro will
  136. // do the entire conversion)
  137. if (dwError & (APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR))
  138. {
  139. hr = HRESULT_FROM_SETUPAPI(dwError);
  140. }
  141. else
  142. {
  143. hr = HRESULT_FROM_WIN32(dwError);
  144. }
  145. return hr;
  146. }
  147. //+---------------------------------------------------------------------------
  148. //
  149. // Function: HrGetProcAddress
  150. //
  151. // Purpose: Loads a libray and returns the address of a procedure within
  152. // the library
  153. //
  154. // Arguments:
  155. // hModule [in] The handle to the library module instance
  156. // pszaFunction [in] Function to retrieve
  157. // ppfn [out] Address of szFunction
  158. //
  159. // Returns: S_OK if successful, Win32 converted error if failure.
  160. //
  161. // Author: billbe 10 June 1997
  162. //
  163. // Notes:
  164. //
  165. HRESULT
  166. HrGetProcAddress (
  167. HMODULE hModule,
  168. PCSTR pszaFunction,
  169. FARPROC* ppfn)
  170. {
  171. Assert(hModule);
  172. Assert(pszaFunction);
  173. Assert(ppfn);
  174. HRESULT hr = S_OK;
  175. *ppfn = GetProcAddress(hModule, pszaFunction);
  176. if (!*ppfn)
  177. {
  178. hr = HrFromLastWin32Error();
  179. TraceTag(ttidError, "HrGetProcAddress failed: szFunction: %s",
  180. pszaFunction);
  181. }
  182. TraceError("HrGetProcAddress", hr);
  183. return hr;
  184. }
  185. //+---------------------------------------------------------------------------
  186. //
  187. // Function: HrLoadLibAndGetProcs
  188. //
  189. // Purpose: Load a dynamic link library and the addresses of one or
  190. // more procedures within that library.
  191. //
  192. // Arguments:
  193. // pszLibPath [in] Path to the DLL to load.
  194. // cFunctions [in] Number of procedures to load.
  195. // apszaFunctionNames [in] Array of function names. (Must be 'cFunctions'
  196. // of them.)
  197. // phmod [out] Returned handle to the loaded module.
  198. // apfn [out] Array of returned pointers to the procedures
  199. // loaded. (Must be 'cFunctions' of them.)
  200. //
  201. // Returns: S_OK if all procedures were loaded, S_FALSE if only
  202. // some of them were, or a Win32 error code. If only
  203. // one procedure is to be loaded and it is not, S_FALSE will
  204. // not be returned, rather, the reason for why the single
  205. // procedure could not be loaded will be returned. This allows
  206. // HrLoadLibAndGetProc to be implemented using this function.
  207. //
  208. // Author: shaunco 19 Jan 1998
  209. //
  210. // Notes: phmod should be freed by the caller using FreeLibrary if
  211. // the return value is S_OK.
  212. //
  213. HRESULT
  214. HrLoadLibAndGetProcs (
  215. PCTSTR pszLibPath,
  216. UINT cFunctions,
  217. const PCSTR* apszaFunctionNames,
  218. HMODULE* phmod,
  219. FARPROC* apfn)
  220. {
  221. Assert (pszLibPath);
  222. Assert (cFunctions);
  223. Assert (apszaFunctionNames);
  224. Assert (phmod);
  225. Assert (apfn);
  226. HRESULT hr = S_OK;
  227. // Load the module and initialize the output parameters.
  228. //
  229. HMODULE hmod = LoadLibrary(pszLibPath);
  230. *phmod = hmod;
  231. ZeroMemory (apfn, cFunctions * sizeof(FARPROC));
  232. if (hmod)
  233. {
  234. // Get the proc address of each function.
  235. //
  236. for (UINT i = 0; i < cFunctions; i++)
  237. {
  238. apfn[i] = GetProcAddress (hmod, apszaFunctionNames[i]);
  239. if (!apfn[i])
  240. {
  241. // Couldn't load all functions. We'll be returning S_FALSE
  242. // (if their are more than one function.)
  243. //
  244. hr = S_FALSE;
  245. TraceTag (ttidError, "HrLoadLibAndGetProcs: GetProcAddress "
  246. "for '%s' failed.",
  247. apszaFunctionNames[i]);
  248. }
  249. }
  250. // If we're only loading one function, and it failed,
  251. // return the failure.
  252. //
  253. if ((1 == cFunctions) && !apfn[0])
  254. {
  255. hr = HrFromLastWin32Error ();
  256. FreeLibrary (hmod);
  257. }
  258. }
  259. else
  260. {
  261. hr = HrFromLastWin32Error ();
  262. TraceTag (ttidError, "HrLoadLibAndGetProcs: LoadLibraryW (%S) failed.",
  263. pszLibPath);
  264. }
  265. TraceError ("HrLoadLibAndGetProcs", hr);
  266. return hr;
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Function: FFileExists
  271. //
  272. // Purpose: Check for file existance. Returns TRUE if file is present,
  273. // FALSE otherwise (duh).
  274. //
  275. // Arguments:
  276. // pszFileName [in] File name to check for.
  277. // fDirectory [in] TRUE if the file is really a directory
  278. //
  279. // Returns:
  280. //
  281. // Author: jeffspr 13 Jan 2000
  282. //
  283. // Notes:
  284. //
  285. BOOL FFileExists(LPTSTR pszFileName, BOOL fDirectory)
  286. {
  287. BOOL fReturn = TRUE;
  288. HANDLE hFile = NULL;
  289. DWORD dwFlags;
  290. if (fDirectory)
  291. {
  292. dwFlags = FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS;
  293. }
  294. else
  295. {
  296. dwFlags = FILE_ATTRIBUTE_NORMAL;
  297. }
  298. hFile = CreateFile(
  299. pszFileName,
  300. GENERIC_READ,
  301. FILE_SHARE_READ | FILE_SHARE_WRITE,
  302. NULL,
  303. OPEN_EXISTING,
  304. dwFlags,
  305. NULL);
  306. if (hFile == INVALID_HANDLE_VALUE)
  307. {
  308. fReturn = FALSE;
  309. goto Exit;
  310. }
  311. Exit:
  312. if (hFile && hFile != INVALID_HANDLE_VALUE)
  313. {
  314. CloseHandle(hFile);
  315. hFile = NULL;
  316. }
  317. return fReturn;
  318. }