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.

756 lines
22 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <stdio.h>
  4. #include <urlmon.h>
  5. #include <msnotify.h>
  6. #include <webcheck.h>
  7. #include <wininet.h>
  8. #include <mstask.h>
  9. #include <inetreg.h>
  10. #include "schedcdf.h"
  11. LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
  12. // This is where we do most of the actual work
  13. void StartOperation(LPSTR lpCDFName);
  14. // Our Dialog Proc function for the Use Other CDF dialog
  15. BOOL CALLBACK UseOtherCDFDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
  16. // Helper Functions
  17. HRESULT WriteDWORD(IPropertyMap *pPropertyMap, LPWSTR szName, DWORD dwVal);
  18. HRESULT WriteBSTR(IPropertyMap *pPropertyMap, LPWSTR szName, LPWSTR szVal);
  19. HRESULT WriteLONGLONG(IPropertyMap *pPropertyMap, LPCWSTR szName, LONGLONG llVal);
  20. HRESULT ReadBSTR(IPropertyMap *pPropertyMap, LPWSTR szName, BSTR *bstrRet);
  21. void WriteToScreen(LPSTR lpText, HRESULT hr);
  22. void DBGOut(LPSTR psz);
  23. // Functions called by NotificationSink Object
  24. HRESULT OnBeginReport(INotification *pNotification, INotificationReport *pNotificationReport);
  25. HRESULT OnEndReport(INotification *pNotification);
  26. HANDLE g_hHeap = NULL;
  27. int g_iActive=0;
  28. int g_BufSize=0;
  29. LPSTR lpEditBuffer;
  30. HINSTANCE hInstance;
  31. HWND hwndEdit;
  32. void DBGOut(LPSTR psz)
  33. {
  34. #ifdef DEBUG
  35. OutputDebugString("SchedCDF: ");
  36. OutputDebugString(psz);
  37. OutputDebugString("\n");
  38. #endif //DEBUG
  39. }
  40. class MySink : public INotificationSink
  41. {
  42. long m_cRef;
  43. public:
  44. MySink() { m_cRef = 1; }
  45. ~MySink() {}
  46. // IUnknown members
  47. STDMETHODIMP QueryInterface(REFIID riid, void **punk);
  48. STDMETHODIMP_(ULONG) AddRef(void);
  49. STDMETHODIMP_(ULONG) Release(void);
  50. // INotificationSink members
  51. STDMETHODIMP OnNotification(
  52. INotification *pNotification,
  53. INotificationReport *pNotificationReport,
  54. DWORD dwReserved);
  55. };
  56. STDMETHODIMP_(ULONG) MySink::AddRef(void)
  57. {
  58. return ++m_cRef;
  59. }
  60. STDMETHODIMP_(ULONG) MySink::Release(void)
  61. {
  62. if( 0L != --m_cRef )
  63. return m_cRef;
  64. delete this;
  65. return 0L;
  66. }
  67. STDMETHODIMP MySink::QueryInterface(REFIID riid, void ** ppv)
  68. {
  69. *ppv=NULL;
  70. // Validate requested interface
  71. if ((IID_IUnknown == riid) ||
  72. (IID_INotificationSink == riid))
  73. *ppv=(INotificationSink *)this;
  74. // Addref through the interface
  75. if( NULL != *ppv ) {
  76. ((LPUNKNOWN)*ppv)->AddRef();
  77. return NOERROR;
  78. }
  79. return E_NOINTERFACE;
  80. }
  81. //
  82. // INotificationSink members
  83. //
  84. STDMETHODIMP MySink::OnNotification(
  85. INotification *pNotification,
  86. INotificationReport *pNotificationReport,
  87. DWORD dwReserved)
  88. {
  89. NOTIFICATIONTYPE nt;
  90. HRESULT hr=S_OK;
  91. DBGOut("SchedCDF sink receiving OnNotification");
  92. hr = pNotification->GetNotificationInfo(&nt, NULL,NULL,NULL,0);
  93. if (FAILED(hr))
  94. {
  95. DBGOut("Failed to get notification type!");
  96. return E_INVALIDARG;
  97. }
  98. if (IsEqualGUID(nt, NOTIFICATIONTYPE_BEGIN_REPORT))
  99. hr = OnBeginReport(pNotification, pNotificationReport);
  100. else if (IsEqualGUID(nt, NOTIFICATIONTYPE_END_REPORT))
  101. hr = OnEndReport(pNotification);
  102. else DBGOut("NotSend: Unknown notification type received");
  103. // Avoid bogus assert
  104. if (SUCCEEDED(hr)) hr = S_OK;
  105. return hr;
  106. }
  107. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  108. {
  109. static char szAppName[] = "CDF Agent Notification Delivery Tool";
  110. HWND hwnd;
  111. MSG msg;
  112. WNDCLASSEX wndclass;
  113. HACCEL hAccel;
  114. wndclass.cbSize = sizeof(wndclass);
  115. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  116. wndclass.lpfnWndProc = WndProc;
  117. wndclass.cbClsExtra = 0;
  118. wndclass.cbWndExtra = 0;
  119. wndclass.hInstance = hInstance;
  120. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  121. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  122. wndclass.hbrBackground = (HBRUSH) GetStockObject (GRAY_BRUSH);
  123. wndclass.lpszMenuName = MAKEINTRESOURCE(SCHEDCDF);
  124. wndclass.lpszClassName = szAppName;
  125. wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  126. RegisterClassEx(&wndclass);
  127. hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  128. CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  129. ShowWindow(hwnd, iCmdShow);
  130. UpdateWindow(hwnd);
  131. while(GetMessage(&msg, NULL, 0, 0))
  132. {
  133. TranslateMessage(&msg);
  134. DispatchMessage(&msg);
  135. }
  136. return msg.wParam;
  137. }
  138. LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  139. {
  140. MySink *pSink = NULL;
  141. RECT rcClientWnd;
  142. HRESULT hr;
  143. INotificationMgr *pNotificationMgr = NULL;
  144. LPNOTIFICATION pNotification = NULL;
  145. NOTIFICATIONITEM NotItem;
  146. NOTIFICATIONCOOKIE ncCookie;
  147. TASK_TRIGGER tt;
  148. TASK_DATA td;
  149. LPSTR lpBuffer = NULL;
  150. DWORD dwStartTime = 0;
  151. MSG msg;
  152. SYSTEMTIME st;
  153. ZeroMemory(&tt, sizeof(TASK_TRIGGER));
  154. ZeroMemory(&td, sizeof(TASK_DATA));
  155. ZeroMemory(&st, sizeof(SYSTEMTIME));
  156. switch(iMsg)
  157. {
  158. case WM_CREATE:
  159. {
  160. OleInitialize(NULL);
  161. hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
  162. GetClientRect(hwnd, &rcClientWnd);
  163. hwndEdit = CreateWindow("EDIT", NULL, WS_BORDER | WS_VISIBLE | WS_CHILD
  164. | WS_HSCROLL | ES_MULTILINE, 0, 0, rcClientWnd.right, rcClientWnd.bottom,
  165. hwnd, (HMENU) 1, hInstance, NULL);
  166. ShowWindow(hwndEdit, SW_SHOW);
  167. lpEditBuffer = NULL;
  168. // Alloc a 4k buffer for the edit window
  169. lpEditBuffer = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 4096);
  170. if (lpEditBuffer)
  171. g_BufSize = 4096;
  172. return 0;
  173. }
  174. case WM_SIZE:
  175. {
  176. GetClientRect(hwnd, &rcClientWnd);
  177. SetWindowPos(hwndEdit, HWND_TOP, 0, 0, rcClientWnd.right, rcClientWnd.bottom,
  178. SWP_SHOWWINDOW);
  179. break;
  180. }
  181. case WM_COMMAND:
  182. {
  183. switch(LOWORD(wParam))
  184. {
  185. case ID_EXIT:
  186. {
  187. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  188. return 0;
  189. }
  190. case ID_UPDATESCOPEALL:
  191. {
  192. StartOperation("all.cdf");
  193. return 0;
  194. }
  195. case ID_UPDATESCOPEOFFLINE:
  196. {
  197. StartOperation("offline.cdf");
  198. return 0;
  199. }
  200. case ID_UPDATESCOPEONLINE:
  201. {
  202. StartOperation("online.cdf");
  203. return 0;
  204. }
  205. case ID_UPDATEFRAMESCDF:
  206. {
  207. StartOperation("frames.cdf");
  208. return 0;
  209. }
  210. case ID_USEOTHERCDF:
  211. {
  212. DialogBox(hInstance, MAKEINTRESOURCE(IDD_OTHER), hwnd, UseOtherCDFDialogProc);
  213. return 0;
  214. }
  215. }
  216. break;
  217. }
  218. case WM_DESTROY:
  219. {
  220. if (lpEditBuffer)
  221. {
  222. GlobalFree(lpEditBuffer);
  223. lpEditBuffer = NULL;
  224. }
  225. PostQuitMessage(0);
  226. return 0;
  227. }
  228. break;
  229. }
  230. return DefWindowProc(hwnd, iMsg, wParam, lParam);
  231. }
  232. void StartOperation(LPSTR lpszCDFName)
  233. {
  234. LONG lret = NULL;
  235. DWORD cbSize = NULL;
  236. LPSTR lpszTemp = NULL;
  237. LPSTR lpszCDFUrlPath = NULL;
  238. LPSTR lpszCookie = NULL;
  239. HKEY hKey = NULL;
  240. MySink *pSink = NULL;
  241. INotificationMgr *pNotificationMgr = NULL;
  242. LPNOTIFICATION pNotification = NULL;
  243. NOTIFICATIONITEM NotItem;
  244. NotItem.pNotification = NULL;
  245. NOTIFICATIONCOOKIE ncCookie;
  246. TASK_TRIGGER tt;
  247. TASK_DATA td;
  248. MSG msg;
  249. SYSTEMTIME st;
  250. HRESULT hr;
  251. ZeroMemory(&tt, sizeof(TASK_TRIGGER));
  252. ZeroMemory(&td, sizeof(TASK_DATA));
  253. ZeroMemory(&st, sizeof(SYSTEMTIME));
  254. // Hack: To workaround fault that happens when urlmon calls InternetCloseHandle after wininet
  255. // has been unloaded we'll call into wininet first which will hopefully cause it to stay
  256. // around until urlmon is gone.
  257. DWORD cbPfx = 0;
  258. HANDLE hCacheEntry = NULL;
  259. LPINTERNET_CACHE_ENTRY_INFO lpCE = NULL;
  260. LPSTR lpPfx = NULL;
  261. lpPfx = (LPSTR)GlobalAlloc(GPTR, lstrlen("Log:")+1);
  262. lstrcpy(lpPfx, "Log:");
  263. lpCE = (LPINTERNET_CACHE_ENTRY_INFO)GlobalAlloc(GPTR, 2048);
  264. ASSERT(lpCE);
  265. cbSize = 2048;
  266. hCacheEntry = FindFirstUrlCacheEntry("Log:", lpCE, &cbSize);
  267. if (lpCE)
  268. {
  269. GlobalFree(lpCE);
  270. lpCE = NULL;
  271. }
  272. if (lpPfx)
  273. {
  274. GlobalFree(lpPfx);
  275. lpPfx = NULL;
  276. }
  277. cbSize = 0;
  278. // End Hack
  279. lret = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_SCHEDCDF, 0,
  280. KEY_READ | KEY_WRITE, &hKey);
  281. if (ERROR_SUCCESS != lret)
  282. {
  283. lret = RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_SCHEDCDF, 0, NULL,
  284. REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, NULL);
  285. }
  286. if (ERROR_SUCCESS == lret)
  287. {
  288. lret = RegQueryValueEx(hKey, REGSTR_VAL_CDFURLPATH, 0, NULL, NULL, &cbSize);
  289. if (ERROR_SUCCESS == lret)
  290. {
  291. lpszTemp = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, cbSize+1);
  292. if (lpszTemp)
  293. {
  294. lret = RegQueryValueEx(hKey, REGSTR_VAL_CDFURLPATH, 0, NULL,
  295. (LPBYTE)lpszTemp, &cbSize);
  296. }
  297. }
  298. else // No URL Path to the CDF Found.. use default
  299. {
  300. lpszTemp = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  301. lstrlen("http://ohserv/users/davidhen/")+1);
  302. if (lpszTemp)
  303. {
  304. lstrcpy(lpszTemp, "http://ohserv/users/davidhen/");
  305. }
  306. }
  307. // Add the CDFName to the Path for the final URL
  308. lpszCDFUrlPath = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  309. (lstrlen(lpszTemp) + lstrlen(lpszCDFName) + 1));
  310. lstrcpy(lpszCDFUrlPath, lpszTemp);
  311. lstrcat(lpszCDFUrlPath, lpszCDFName);
  312. if (lpszTemp)
  313. {
  314. GlobalFree(lpszTemp);
  315. lpszTemp = NULL;
  316. }
  317. }
  318. if (hKey)
  319. {
  320. lret = RegQueryValueEx(hKey, lpszCDFName, 0, NULL, NULL, &cbSize);
  321. if (ERROR_SUCCESS == lret)
  322. {
  323. lpszCookie = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, cbSize+1);
  324. if (lpszCookie)
  325. {
  326. lret = RegQueryValueEx(hKey, lpszCDFName, 0, NULL, (LPBYTE)lpszCookie,
  327. &cbSize);
  328. }
  329. }
  330. }
  331. do
  332. {
  333. hr = CoInitialize(NULL);
  334. ASSERT(SUCCEEDED(hr));
  335. hr = CoCreateInstance(CLSID_StdNotificationMgr, NULL, CLSCTX_INPROC,
  336. IID_INotificationMgr, (void**)&pNotificationMgr);
  337. if (FAILED(hr))
  338. {
  339. WriteToScreen("Error: Unable to CoCreateInstance NotificationMgr", NULL);
  340. WriteToScreen(" CoCreateInstance returned:", hr);
  341. break;
  342. }
  343. ASSERT(pNotificationMgr);
  344. pSink = new MySink;
  345. if (lpszCookie)
  346. {
  347. // MAKE_WIDEPTR_FROMANSI is a macro which will create a wide string from an ansi string.
  348. // The first parameter isn't defined before calling and it doesn't need to be freed.
  349. // (handled by the temp buffer class destructor)
  350. MAKE_WIDEPTR_FROMANSI(lpwszCookie, lpszCookie);
  351. // Make a valid cookie from the wide string.
  352. CLSIDFromString(lpwszCookie, &ncCookie);
  353. NotItem.cbSize = sizeof(NOTIFICATIONITEM);
  354. hr = pNotificationMgr->FindNotification(&ncCookie, &NotItem, 0);
  355. if (SUCCEEDED(hr))
  356. {
  357. WriteToScreen("Found Scheduled Notification, Delivering Existing Notification", NULL);
  358. WriteToScreen(" and waiting for End Report...", NULL);
  359. hr = pNotificationMgr->DeliverNotification(NotItem.pNotification, CLSID_ChannelAgent,
  360. (DELIVERMODE)DM_NEED_COMPLETIONREPORT, pSink, NULL, 0);
  361. if (FAILED(hr))
  362. {
  363. WriteToScreen("Error 1: Unable to Deliver First Notification", NULL);
  364. WriteToScreen(" DeliverNotification returned:", hr);
  365. break;
  366. }
  367. WriteToScreen("First Notification Delivered. Waiting for End Report...", NULL);
  368. // Delay until End Report recieved
  369. g_iActive = 1;
  370. while (g_iActive && GetMessage(&msg, NULL, 0, 0))
  371. {
  372. TranslateMessage(&msg);
  373. DispatchMessage(&msg);
  374. }
  375. SAFERELEASE(NotItem.pNotification);
  376. // For Debugging purposes we'll find the notification again to verify Task Trigger
  377. // information for Auto Scheduling
  378. NotItem.cbSize = sizeof (NOTIFICATIONITEM);
  379. hr = pNotificationMgr->FindNotification(&ncCookie, &NotItem, 0);
  380. SAFERELEASE(NotItem.pNotification);
  381. WriteToScreen("Finished Successfully", NULL);
  382. break;
  383. }
  384. else
  385. {
  386. WriteToScreen("Warning, Cookie string found in registry but we were unable to find the", NULL);
  387. WriteToScreen(" scheduled Notification. Creating a new notification instead", NULL);
  388. // Because the notification couldn't be found we'll go through the same path as creating
  389. // a new notification.
  390. }
  391. }
  392. GetSystemTime(&st);
  393. tt.cbTriggerSize = sizeof(TASK_TRIGGER);
  394. tt.wBeginYear = st.wYear;
  395. tt.wBeginMonth = st.wMonth;
  396. tt.wBeginDay = st.wDay;
  397. tt.wStartHour = st.wHour;
  398. tt.wStartMinute = st.wMinute;
  399. tt.MinutesInterval = 10;
  400. tt.MinutesDuration = 60;
  401. tt.Type.Daily.DaysInterval = 1;
  402. tt.TriggerType = TASK_TIME_TRIGGER_DAILY;
  403. tt.rgFlags = TASK_FLAG_DISABLED;
  404. td.cbSize = sizeof(TASK_DATA);
  405. td.dwTaskFlags = TASK_FLAG_START_ONLY_IF_IDLE;
  406. hr = pNotificationMgr->CreateNotification(NOTIFICATIONTYPE_AGENT_START,
  407. (NOTIFICATIONFLAGS) 0, NULL, &pNotification, 0);
  408. if (FAILED(hr))
  409. {
  410. WriteToScreen("Error: Unable to CreateNotification", NULL);
  411. WriteToScreen(" CreateNotification returned:", hr);
  412. break;
  413. }
  414. ASSERT(pNotification);
  415. MAKE_WIDEPTR_FROMANSI(lpwszCDFUrl, lpszCDFUrlPath);
  416. WriteBSTR(pNotification, L"URL", lpwszCDFUrl);
  417. WriteDWORD(pNotification, L"Priority", 0);
  418. WriteDWORD(pNotification, L"RecurseLevels", 2);
  419. WriteDWORD(pNotification, L"RecurseFlags", (DWORD)WEBCRAWL_LINKS_ELSEWHERE);
  420. WriteDWORD(pNotification, L"ChannelFlags", (DWORD)CHANNEL_AGENT_DYNAMIC_SCHEDULE);
  421. // WriteBSTR(pNotification, L"PostURL", L"http://ohserv/scripts/davidhen/davidhen.pl");
  422. // WriteLONGLONG(pNotification, L"LogGroupID", (LONGLONG)0);
  423. // WriteDWORD(pNotification, L"PostFailureRetry", 0);
  424. hr = pNotificationMgr->ScheduleNotification(pNotification, CLSID_ChannelAgent,
  425. &tt, &td, (DELIVERMODE)0, NULL, NULL, NULL, &ncCookie, 0);
  426. if (FAILED(hr))
  427. {
  428. WriteToScreen("Error: ScheduleNotification Failed", NULL);
  429. WriteToScreen(" ScheduleNotification returned:", hr);
  430. break;
  431. }
  432. // Save the cookie to the registry for future updates to this channel
  433. if (hKey)
  434. {
  435. WCHAR wszCookie[GUIDSTR_MAX];
  436. StringFromGUID2(ncCookie, wszCookie, sizeof(wszCookie));
  437. MAKE_ANSIPTR_FROMWIDE(szCookie, wszCookie);
  438. cbSize = lstrlen(szCookie)+1;
  439. RegSetValueEx(hKey, lpszCDFName, 0, REG_SZ, (LPBYTE)szCookie, cbSize);
  440. }
  441. SAFERELEASE(pNotification);
  442. NotItem.cbSize = sizeof (NOTIFICATIONITEM);
  443. hr = pNotificationMgr->FindNotification(&ncCookie, &NotItem, 0);
  444. if (FAILED(hr))
  445. {
  446. WriteToScreen("Error 1: Unable to Find Scheduled Notification", NULL);
  447. WriteToScreen(" FindNotification returned:", hr);
  448. break;
  449. }
  450. hr = pNotificationMgr->DeliverNotification(NotItem.pNotification, CLSID_ChannelAgent,
  451. (DELIVERMODE)DM_NEED_COMPLETIONREPORT, pSink, NULL, 0);
  452. if (FAILED(hr))
  453. {
  454. WriteToScreen("Error 1: Unable to Deliver First Notification", NULL);
  455. WriteToScreen(" DeliverNotification returned:", hr);
  456. break;
  457. }
  458. WriteToScreen("First Notification Delivered. Waiting for End Report...", NULL);
  459. // Delay until End Report recieved
  460. g_iActive = 1;
  461. while (g_iActive && GetMessage(&msg, NULL, 0, 0))
  462. {
  463. TranslateMessage(&msg);
  464. DispatchMessage(&msg);
  465. }
  466. SAFERELEASE(NotItem.pNotification);
  467. NotItem.cbSize = sizeof (NOTIFICATIONITEM);
  468. hr = pNotificationMgr->FindNotification(&ncCookie, &NotItem, 0);
  469. if (FAILED(hr))
  470. {
  471. WriteToScreen("Error 2: Unable to Find Scheduled Notification", NULL);
  472. WriteToScreen(" FindNotification returned:", hr);
  473. break;
  474. }
  475. hr = pNotificationMgr->DeliverNotification(NotItem.pNotification, CLSID_ChannelAgent,
  476. (DELIVERMODE)DM_NEED_COMPLETIONREPORT, pSink, NULL, 0);
  477. if (FAILED(hr))
  478. {
  479. WriteToScreen("Error 2: Unable to Deliver First Notification", NULL);
  480. WriteToScreen(" DeliverNotification returned:", hr);
  481. break;
  482. }
  483. WriteToScreen("Second Notification Delivered. Waiting for End Report ...", NULL);
  484. // Delay until End Report recieved
  485. g_iActive = 1;
  486. while (g_iActive && GetMessage(&msg, NULL, 0, 0))
  487. {
  488. TranslateMessage(&msg);
  489. DispatchMessage(&msg);
  490. }
  491. WriteToScreen("Finished Successfully", NULL);
  492. break;
  493. }
  494. while (TRUE);
  495. SAFERELEASE(NotItem.pNotification);
  496. SAFERELEASE(pNotification);
  497. SAFERELEASE(pSink);
  498. SAFERELEASE(pNotificationMgr);
  499. if (hKey)
  500. {
  501. RegCloseKey(hKey);
  502. hKey = NULL;
  503. }
  504. return;
  505. }
  506. BOOL CALLBACK UseOtherCDFDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  507. {
  508. switch (iMsg)
  509. {
  510. case WM_INITDIALOG:
  511. {
  512. HWND hwndEditBox = GetDlgItem(hDlg, IDC_CDFNAME);
  513. SetFocus(hwndEditBox);
  514. return TRUE;
  515. }
  516. case WM_COMMAND:
  517. {
  518. switch (LOWORD(wParam))
  519. {
  520. case IDOK:
  521. {
  522. int iLength = 0;
  523. LPSTR lpszCDFName = NULL;
  524. HWND hwndEditBox = GetDlgItem(hDlg, IDC_CDFNAME);
  525. iLength = GetWindowTextLength(hwndEditBox);
  526. if (0 == iLength)
  527. {
  528. MessageBox(NULL, "No CDF filename Specified.. Enter CDF filename before selecting OK", "Error", MB_OK);
  529. break;
  530. }
  531. EndDialog(hDlg, 0);
  532. lpszCDFName = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, iLength+1);
  533. if (lpszCDFName)
  534. {
  535. GetWindowText(hwndEditBox, lpszCDFName, iLength+1);
  536. StartOperation(lpszCDFName);
  537. GlobalFree(lpszCDFName);
  538. lpszCDFName = NULL;
  539. }
  540. return TRUE;
  541. }
  542. case IDCANCEL:
  543. {
  544. EndDialog(hDlg, 0);
  545. return TRUE;
  546. }
  547. break;
  548. }
  549. }
  550. }
  551. return FALSE;
  552. }
  553. /////////////////////////////////////////////////////////////////////////////
  554. //
  555. // Helper Functions
  556. //
  557. HRESULT WriteDWORD(IPropertyMap *pPropertyMap, LPWSTR szName, DWORD dwVal)
  558. {
  559. VARIANT Val;
  560. Val.vt = VT_I4;
  561. Val.lVal = dwVal;
  562. return pPropertyMap->Write(szName, Val, 0);
  563. }
  564. HRESULT WriteBSTR(IPropertyMap *pPropertyMap, LPWSTR szName, LPWSTR szVal)
  565. {
  566. VARIANT Val;
  567. Val.vt = VT_BSTR;
  568. Val.bstrVal = SysAllocString(szVal);
  569. HRESULT hr = pPropertyMap->Write(szName, Val, 0);
  570. SysFreeString(Val.bstrVal);
  571. return hr;
  572. }
  573. HRESULT WriteLONGLONG(IPropertyMap *pPropertyMap, LPCWSTR szName, LONGLONG llVal)
  574. {
  575. VARIANT Val;
  576. Val.vt = VT_CY;
  577. Val.cyVal = *(CY *)&llVal;
  578. return pPropertyMap->Write(szName, Val, 0);
  579. }
  580. HRESULT ReadBSTR(IPropertyMap *pPropertyMap, LPWSTR szName, BSTR *bstrRet)
  581. {
  582. VARIANT Val;
  583. Val.vt = VT_EMPTY;
  584. if (SUCCEEDED(pPropertyMap->Read(szName, &Val)) &&
  585. (Val.vt==VT_BSTR))
  586. {
  587. *bstrRet = Val.bstrVal;
  588. return S_OK;
  589. }
  590. else
  591. {
  592. VariantClear(&Val); // free any return value of wrong type
  593. *bstrRet = NULL;
  594. return E_INVALIDARG;
  595. }
  596. }
  597. void WriteToScreen(LPSTR lpText, HRESULT hr)
  598. {
  599. char tmp[150];
  600. int BufStrLength = 0;
  601. int NewStrLength = 0;
  602. LPSTR lpTempBuf = NULL;
  603. if (!lpEditBuffer)
  604. return;
  605. if (hr)
  606. {
  607. wsprintf(tmp, "%s %x\r\n", lpText, hr);
  608. }
  609. else
  610. {
  611. wsprintf(tmp, "%s\r\n", lpText);
  612. }
  613. BufStrLength = lstrlen(lpEditBuffer);
  614. NewStrLength = lstrlen(tmp);
  615. if ((BufStrLength + NewStrLength) >= g_BufSize)
  616. {
  617. lpEditBuffer = (LPSTR)GlobalReAlloc((HGLOBAL)lpEditBuffer, g_BufSize+4096, GMEM_FIXED | GMEM_ZEROINIT);
  618. g_BufSize += 4096;
  619. }
  620. lstrcat(lpEditBuffer, tmp);
  621. Edit_SetText(hwndEdit, lpEditBuffer);
  622. }
  623. HRESULT OnBeginReport(INotification *pNotification, INotificationReport *pNotificationReport)
  624. {
  625. DBGOut("BeginReport received");
  626. return S_OK;
  627. }
  628. HRESULT OnEndReport(INotification *pNotification)
  629. {
  630. DBGOut("EndReport received");
  631. BSTR bstrEndStatus=NULL;
  632. ReadBSTR(pNotification, L"StatusString", &bstrEndStatus);
  633. g_iActive = 0;
  634. return S_OK;
  635. }