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.

433 lines
9.5 KiB

  1. /**
  2. * Asynchronous pluggable protocol for Applications
  3. *
  4. * Copyright (C) Microsoft Corporation, 2000
  5. */
  6. /////////////////////////////////////////////////////////////////////////////
  7. /////////////////////////////////////////////////////////////////////////////
  8. /////////////////////////////////////////////////////////////////////////////
  9. #include "precomp.h"
  10. #include "app.h"
  11. /////////////////////////////////////////////////////////////////////////////
  12. /////////////////////////////////////////////////////////////////////////////
  13. /////////////////////////////////////////////////////////////////////////////
  14. // Private globals
  15. HINSTANCE g_DllInstance;
  16. long g_DllObjectCount;
  17. // Prototypes
  18. extern "C"
  19. {
  20. BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
  21. STDAPI DllCanUnloadNow();
  22. STDAPI DllGetClassObject(REFCLSID, REFIID, LPVOID*);
  23. STDAPI DllRegisterServer();
  24. STDAPI DllUnregisterServer();
  25. }
  26. /*HRESULT
  27. InitDll()
  28. {
  29. HRESULT hr;
  30. //LoadLibrary(L"XSPISAPI.DLL"); // to disable unloading
  31. //hr = InitThreadPool();
  32. //ON_ERROR_EXIT();
  33. // hr = InitCodeGenerator();
  34. // if (FAILED(hr))
  35. // goto exit;
  36. // hr = DllInitProcessModel();
  37. //if (FAILED(hr))
  38. // goto exit;
  39. //exit:
  40. hr = S_OK;
  41. return hr;
  42. }*/
  43. /*HRESULT
  44. UninitDll()
  45. {
  46. HRESULT hr;
  47. // hr = UninitCodeGenerator();
  48. hr = S_OK;
  49. return hr;
  50. }*/
  51. BOOL WINAPI
  52. DllMain(
  53. HINSTANCE Instance,
  54. DWORD Reason,
  55. LPVOID)
  56. {
  57. HRESULT hr = S_OK;
  58. BOOL ret = TRUE;
  59. switch (Reason)
  60. {
  61. case DLL_PROCESS_ATTACH:
  62. // remember the instance
  63. g_DllInstance = Instance;
  64. DisableThreadLibraryCalls(Instance);
  65. // hr = InitDll();
  66. if (hr)
  67. {
  68. ret = FALSE;
  69. goto exit;
  70. }
  71. break;
  72. case DLL_PROCESS_DETACH:
  73. // hr = UninitDll();
  74. break;
  75. default:
  76. break;
  77. }
  78. exit:
  79. return ret;
  80. }
  81. ULONG
  82. IncrementDllObjectCount()
  83. {
  84. return InterlockedIncrement(&g_DllObjectCount);
  85. }
  86. ULONG
  87. DecrementDllObjectCount()
  88. {
  89. ULONG count = InterlockedDecrement(&g_DllObjectCount);
  90. if (count == 0)
  91. {
  92. TerminateAppProtocol();
  93. }
  94. return count;
  95. }
  96. STDAPI
  97. DllCanUnloadNow()
  98. {
  99. // TODO: Make this code thread safe.
  100. return g_DllObjectCount > 0 ? S_FALSE : S_OK;
  101. }
  102. STDAPI
  103. DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *ppv)
  104. {
  105. HRESULT hr = S_OK;
  106. if (clsid == CLSID_AppProtocol)
  107. {
  108. hr = GetAppProtocolClassObject(iid, ppv);
  109. if (FAILED(hr))
  110. goto exit;
  111. }
  112. else
  113. {
  114. hr = CLASS_E_CLASSNOTAVAILABLE;
  115. goto exit;
  116. }
  117. exit:
  118. return hr;
  119. }
  120. // for errors define
  121. #include <olectl.h>
  122. STDAPI
  123. DllRegisterServer()
  124. {
  125. // BUGBUG: for now! copy code from register.cxx XSP later
  126. return SELFREG_E_CLASS;
  127. }
  128. STDAPI
  129. DllUnregisterServer()
  130. {
  131. // BUGBUG: for now! copy code from register.cxx XSP later
  132. return SELFREG_E_CLASS;
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. /////////////////////////////////////////////////////////////////////////////
  136. /////////////////////////////////////////////////////////////////////////////
  137. BOOL (WINAPI * g_pInternetSetCookieW ) (LPCTSTR, LPCTSTR, LPCTSTR) = NULL;
  138. BOOL (WINAPI * g_pInternetGetCookieW ) (LPCTSTR, LPCTSTR, LPTSTR, LPDWORD) = NULL;
  139. HINTERNET (WINAPI * g_pInternetOpen ) (LPCTSTR, DWORD, LPCTSTR, LPCTSTR, DWORD) = NULL;
  140. void (WINAPI * g_pInternetCloseHandle ) (HINTERNET) = NULL;
  141. HINTERNET (WINAPI * g_pInternetOpenUrl ) (HINTERNET, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD_PTR) = NULL;
  142. BOOL (WINAPI * g_pInternetReadFile ) (HINTERNET, LPVOID, DWORD, LPDWORD) = NULL;
  143. BOOL (WINAPI * g_pInternetQueryOption ) (HINTERNET, DWORD, LPVOID, LPDWORD) = NULL;
  144. /////////////////////////////////////////////////////////////////////////////
  145. /////////////////////////////////////////////////////////////////////////////
  146. /////////////////////////////////////////////////////////////////////////////
  147. HRESULT InitializeAppProtocol()
  148. {
  149. if (g_fStarted)
  150. return TRUE;
  151. HRESULT hr = S_OK;
  152. HINSTANCE hWinInet = NULL;
  153. ////////////////////////////////////////////////////////////
  154. // Step 3: Obtain entry points from WININET.DLL
  155. hWinInet = GetModuleHandle(L"WININET.DLL");
  156. if(hWinInet == NULL)
  157. hWinInet = LoadLibrary(L"WININET.DLL");
  158. if(hWinInet == NULL)
  159. {
  160. hr = GetLastWin32Error();
  161. goto exit;
  162. }
  163. g_pInternetSetCookieW = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPCTSTR))
  164. GetProcAddress(hWinInet, "InternetSetCookieW");
  165. g_pInternetGetCookieW = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPTSTR, LPDWORD))
  166. GetProcAddress(hWinInet, "InternetGetCookieW");
  167. g_pInternetOpen = (HINTERNET (WINAPI *)(LPCTSTR, DWORD, LPCTSTR, LPCTSTR, DWORD))
  168. GetProcAddress(hWinInet, "InternetOpenW");
  169. g_pInternetCloseHandle = (void (WINAPI *)(HINTERNET))
  170. GetProcAddress(hWinInet, "InternetCloseHandle");
  171. g_pInternetOpenUrl = (HINTERNET (WINAPI *)(HINTERNET, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD_PTR))
  172. GetProcAddress(hWinInet, "InternetOpenUrlW");
  173. g_pInternetReadFile = (BOOL (WINAPI *)(HINTERNET, LPVOID, DWORD, LPDWORD))
  174. GetProcAddress(hWinInet, "InternetReadFile");
  175. g_pInternetQueryOption = (BOOL (WINAPI *)(HINTERNET, DWORD, LPVOID, LPDWORD))
  176. GetProcAddress(hWinInet, "InternetQueryOptionW");
  177. if ( g_pInternetSetCookieW == NULL ||
  178. g_pInternetGetCookieW == NULL ||
  179. g_pInternetOpen == NULL ||
  180. g_pInternetCloseHandle == NULL ||
  181. g_pInternetOpenUrl == NULL ||
  182. g_pInternetReadFile == NULL ||
  183. g_pInternetQueryOption == NULL )
  184. {
  185. hr = GetLastWin32Error();
  186. goto exit;
  187. }
  188. g_fStarted = TRUE;
  189. exit:
  190. // ???? freelibrary later?
  191. return hr;
  192. }
  193. /////////////////////////////////////////////////////////////////////////////
  194. /////////////////////////////////////////////////////////////////////////////
  195. /////////////////////////////////////////////////////////////////////////////
  196. HRESULT
  197. GetAppProtocolClassObject(
  198. REFIID iid,
  199. void ** ppv)
  200. {
  201. HRESULT hr;
  202. hr = InitializeAppProtocol();
  203. if (FAILED(hr))
  204. goto exit;
  205. hr = g_AppProtocolFactory.QueryInterface(iid, ppv);
  206. if (FAILED(hr))
  207. goto exit;
  208. exit:
  209. return hr;
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. /////////////////////////////////////////////////////////////////////////////
  213. /////////////////////////////////////////////////////////////////////////////
  214. LPWSTR
  215. DuplicateString ( LPCWSTR szString)
  216. {
  217. if (szString == NULL)
  218. return NULL;
  219. LPWSTR szReturn = (LPWSTR) MemAlloc((wcslen(szString) + 1) * sizeof(WCHAR));
  220. if (szReturn != NULL)
  221. wcscpy(szReturn, szString);
  222. return szReturn;
  223. }
  224. /////////////////////////////////////////////////////////////////////////////
  225. /////////////////////////////////////////////////////////////////////////////
  226. /////////////////////////////////////////////////////////////////////////////
  227. // Cleanup for process shutdown.
  228. //????????
  229. BOOL WINAPI TerminateExtension(DWORD)
  230. {
  231. return TRUE;
  232. }
  233. void
  234. TerminateAppProtocol()
  235. {
  236. // TODO: This is never called. Figure out how to get proper shutdown. Consider possible refcount leaks.
  237. if (g_fStarted)
  238. {
  239. TerminateExtension(0); // this is in xspprobe.cxx, but doesn't do anything!
  240. g_fStarted = FALSE;
  241. }
  242. }
  243. /**
  244. * Allocate memory block.
  245. */
  246. void *
  247. MemAlloc(
  248. size_t size)
  249. {
  250. return (void *)HeapAlloc(GetProcessHeap(), 0, size);
  251. }
  252. /**
  253. * Allocate memory block and zero it out.
  254. */
  255. void *
  256. MemAllocClear(
  257. size_t size)
  258. {
  259. return (void *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
  260. }
  261. /**
  262. * Free allocated memory block.
  263. */
  264. void
  265. MemFree(
  266. void *pMem)
  267. {
  268. if (pMem != NULL)
  269. HeapFree(GetProcessHeap(), 0, pMem);
  270. }
  271. /**
  272. * Free allocated memory block, then clear the reference.
  273. */
  274. void
  275. MemClearFn(void **ppMem)
  276. {
  277. if (*ppMem != NULL)
  278. {
  279. HeapFree(GetProcessHeap(), 0, *ppMem);
  280. *ppMem = NULL;
  281. }
  282. }
  283. /**
  284. * Reallocate memory block
  285. */
  286. void *
  287. MemReAlloc(
  288. void *pMem,
  289. size_t NewSize)
  290. {
  291. void *pResult = NULL;
  292. if (pMem != NULL)
  293. {
  294. pResult = (void *)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pMem, NewSize);
  295. } else {
  296. pResult = (void *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NewSize);
  297. }
  298. return pResult;
  299. }
  300. /**
  301. * Get the size of a memory block.
  302. */
  303. size_t
  304. MemGetSize(void *pv)
  305. {
  306. int result;
  307. if (pv == NULL)
  308. return 0;
  309. result = HeapSize(GetProcessHeap(), 0, pv);
  310. // ASSERT(result != -1);
  311. return result;
  312. }
  313. /**
  314. * Copy memory block
  315. */
  316. void *
  317. MemDup(void *pMem, int cb)
  318. {
  319. void *p = MemAlloc(cb);
  320. if (p == NULL)
  321. return NULL;
  322. CopyMemory(p, pMem, cb);
  323. return p;
  324. }
  325. void
  326. ClearInterfaceFn(
  327. IUnknown ** ppUnk)
  328. {
  329. IUnknown * pUnk;
  330. pUnk = *ppUnk;
  331. *ppUnk = NULL;
  332. if (pUnk)
  333. pUnk->Release();
  334. }
  335. void
  336. ReplaceInterfaceFn(
  337. IUnknown ** ppUnk,
  338. IUnknown * pUnk)
  339. {
  340. IUnknown * pUnkOld = *ppUnk;
  341. *ppUnk = pUnk;
  342. // Note that we do AddRef before Release; this avoids
  343. // accidentally destroying an object if this function
  344. // is passed two aliases to it
  345. if (pUnk)
  346. pUnk->AddRef();
  347. if (pUnkOld)
  348. pUnkOld->Release();
  349. }