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.

744 lines
20 KiB

  1. // CentralFMSvc.cpp : Implementation of WinMain
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f CentralFMSvcps.mk in the project directory.
  5. #include "stdafx.h"
  6. #include "resource.h"
  7. #include <initguid.h>
  8. #include "CentralFMSvc.h"
  9. #include "CentralFMSvc_i.c"
  10. #include <mqoai.h>
  11. #include <mq.h>
  12. #include <TCHAR.h>
  13. #include <Rpcdce.h>
  14. #include <stdio.h>
  15. //#include <mq.h>
  16. //#import "d:\\windows\\system32\\mqoa.dll" no_namespace
  17. CServiceModule _Module;
  18. HANDLE g_hStopEvent = NULL;
  19. BEGIN_OBJECT_MAP(ObjectMap)
  20. END_OBJECT_MAP()
  21. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  22. {
  23. while (p1 != NULL && *p1 != NULL)
  24. {
  25. LPCTSTR p = p2;
  26. while (p != NULL && *p != NULL)
  27. {
  28. if (*p1 == *p)
  29. return CharNext(p1);
  30. p = CharNext(p);
  31. }
  32. p1 = CharNext(p1);
  33. }
  34. return NULL;
  35. }
  36. // Although some of these functions are big they are declared inline since they are only used once
  37. inline HRESULT CServiceModule::RegisterServer(BOOL bRegTypeLib, BOOL bService)
  38. {
  39. HRESULT hr = CoInitialize(NULL);
  40. if (FAILED(hr))
  41. return hr;
  42. // Remove any previous service since it may point to
  43. // the incorrect file
  44. Uninstall();
  45. // Add service entries
  46. UpdateRegistryFromResource(IDR_CentralFMSvc, TRUE);
  47. // Adjust the AppID for Local Server or Service
  48. CRegKey keyAppID;
  49. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
  50. if (lRes != ERROR_SUCCESS)
  51. return lRes;
  52. CRegKey key;
  53. lRes = key.Open(keyAppID, _T("{4E27CC20-0519-4E8C-BFF1-03C0F14DCDDA}"), KEY_WRITE);
  54. if (lRes != ERROR_SUCCESS)
  55. return lRes;
  56. key.DeleteValue(_T("LocalService"));
  57. if (bService)
  58. {
  59. key.SetValue(_T("CentralFMSvc"), _T("LocalService"));
  60. key.SetValue(_T("-Service"), _T("ServiceParameters"));
  61. // Create service
  62. Install();
  63. }
  64. // Add object entries
  65. hr = CComModule::RegisterServer(bRegTypeLib);
  66. CoUninitialize();
  67. return hr;
  68. }
  69. inline HRESULT CServiceModule::UnregisterServer()
  70. {
  71. HRESULT hr = CoInitialize(NULL);
  72. if (FAILED(hr))
  73. return hr;
  74. // Remove service entries
  75. UpdateRegistryFromResource(IDR_CentralFMSvc, FALSE);
  76. // Remove service
  77. Uninstall();
  78. // Remove object entries
  79. CComModule::UnregisterServer(TRUE);
  80. CoUninitialize();
  81. return S_OK;
  82. }
  83. inline void CServiceModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, UINT nServiceNameID, const GUID* plibid)
  84. {
  85. CComModule::Init(p, h, plibid);
  86. m_bService = TRUE;
  87. LoadString(h, nServiceNameID, m_szServiceName, sizeof(m_szServiceName) / sizeof(TCHAR));
  88. // set up the initial service status
  89. m_hServiceStatus = NULL;
  90. m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  91. m_status.dwCurrentState = SERVICE_STOPPED;
  92. m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  93. m_status.dwWin32ExitCode = 0;
  94. m_status.dwServiceSpecificExitCode = 0;
  95. m_status.dwCheckPoint = 0;
  96. m_status.dwWaitHint = 0;
  97. g_hStopEvent = CreateEvent(
  98. NULL,
  99. FALSE,
  100. FALSE,
  101. s_cszStopEvent
  102. );
  103. if(NULL == g_hStopEvent)
  104. {
  105. LogEvent( _T("Failed to create: %s; hr=%ld"),
  106. s_cszStopEvent,
  107. GetLastError());
  108. }
  109. }
  110. LONG CServiceModule::Unlock()
  111. {
  112. LONG l = CComModule::Unlock();
  113. if (l == 0 && !m_bService)
  114. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  115. return l;
  116. }
  117. BOOL CServiceModule::IsInstalled()
  118. {
  119. BOOL bResult = FALSE;
  120. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  121. if (hSCM != NULL)
  122. {
  123. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
  124. if (hService != NULL)
  125. {
  126. bResult = TRUE;
  127. ::CloseServiceHandle(hService);
  128. }
  129. ::CloseServiceHandle(hSCM);
  130. }
  131. return bResult;
  132. }
  133. inline BOOL CServiceModule::Install()
  134. {
  135. if (IsInstalled())
  136. return TRUE;
  137. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  138. if (hSCM == NULL)
  139. {
  140. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  141. return FALSE;
  142. }
  143. // Get the executable file path
  144. TCHAR szFilePath[_MAX_PATH];
  145. ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
  146. SC_HANDLE hService = ::CreateService(
  147. hSCM, m_szServiceName, m_szServiceName,
  148. SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  149. SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
  150. szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
  151. if (hService == NULL)
  152. {
  153. ::CloseServiceHandle(hSCM);
  154. MessageBox(NULL, _T("Couldn't create service"), m_szServiceName, MB_OK);
  155. return FALSE;
  156. }
  157. SERVICE_FAILURE_ACTIONS Failure;
  158. SC_ACTION Actions[3];
  159. Failure.cActions = 3;
  160. Failure.dwResetPeriod = 1200;
  161. Failure.lpCommand = _T("");
  162. Failure.lpRebootMsg = _T("");
  163. Failure.lpsaActions = Actions;
  164. Actions[0].Delay = 2000;
  165. Actions[0].Type = SC_ACTION_RESTART;
  166. Actions[1].Delay = 2000;
  167. Actions[1].Type = SC_ACTION_RESTART;
  168. Actions[2].Delay = 2000;
  169. Actions[2].Type = SC_ACTION_RESTART;
  170. ::CloseServiceHandle(hService);
  171. ::CloseServiceHandle(hSCM);
  172. return TRUE;
  173. }
  174. inline BOOL CServiceModule::Uninstall()
  175. {
  176. if (!IsInstalled())
  177. return TRUE;
  178. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  179. if (hSCM == NULL)
  180. {
  181. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  182. return FALSE;
  183. }
  184. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_STOP | DELETE);
  185. if (hService == NULL)
  186. {
  187. ::CloseServiceHandle(hSCM);
  188. MessageBox(NULL, _T("Couldn't open service"), m_szServiceName, MB_OK);
  189. return FALSE;
  190. }
  191. SERVICE_STATUS status;
  192. ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
  193. BOOL bDelete = ::DeleteService(hService);
  194. ::CloseServiceHandle(hService);
  195. ::CloseServiceHandle(hSCM);
  196. if (bDelete)
  197. return TRUE;
  198. MessageBox(NULL, _T("Service could not be deleted"), m_szServiceName, MB_OK);
  199. return FALSE;
  200. }
  201. ///////////////////////////////////////////////////////////////////////////////////////
  202. // Logging functions
  203. void CServiceModule::LogEvent(LPCTSTR pFormat, ...)
  204. {
  205. TCHAR chMsg[256];
  206. HANDLE hEventSource;
  207. LPTSTR lpszStrings[1];
  208. va_list pArg;
  209. va_start(pArg, pFormat);
  210. _vstprintf(chMsg, pFormat, pArg);
  211. va_end(pArg);
  212. lpszStrings[0] = chMsg;
  213. if (m_bService)
  214. {
  215. /* Get a handle to use with ReportEvent(). */
  216. hEventSource = RegisterEventSource(NULL, m_szServiceName);
  217. if (hEventSource != NULL)
  218. {
  219. /* Write to event log. */
  220. ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  221. DeregisterEventSource(hEventSource);
  222. }
  223. }
  224. else
  225. {
  226. // As we are not running as a service, just write the error to the console.
  227. _putts(chMsg);
  228. }
  229. }
  230. //////////////////////////////////////////////////////////////////////////////////////////////
  231. // Service startup and registration
  232. inline void CServiceModule::Start()
  233. {
  234. SERVICE_TABLE_ENTRY st[] =
  235. {
  236. { m_szServiceName, _ServiceMain },
  237. { NULL, NULL }
  238. };
  239. if (m_bService && !::StartServiceCtrlDispatcher(st))
  240. {
  241. m_bService = FALSE;
  242. }
  243. if (m_bService == FALSE)
  244. Run();
  245. }
  246. inline void CServiceModule::ServiceMain(DWORD /* dwArgc */, LPTSTR* /* lpszArgv */)
  247. {
  248. // Register the control request handler
  249. m_status.dwCurrentState = SERVICE_START_PENDING;
  250. m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
  251. if (m_hServiceStatus == NULL)
  252. {
  253. LogEvent(_T("Handler not installed"));
  254. return;
  255. }
  256. SetServiceStatus(SERVICE_START_PENDING);
  257. m_status.dwWin32ExitCode = S_OK;
  258. m_status.dwCheckPoint = 0;
  259. m_status.dwWaitHint = 0;
  260. // When the Run function returns, the service has stopped.
  261. Run();
  262. SetServiceStatus(SERVICE_STOPPED);
  263. LogEvent(_T("Service stopped"));
  264. }
  265. inline void CServiceModule::Handler(DWORD dwOpcode)
  266. {
  267. switch (dwOpcode)
  268. {
  269. case SERVICE_CONTROL_STOP:
  270. SetServiceStatus(SERVICE_STOP_PENDING);
  271. if(NULL != g_hStopEvent)
  272. {
  273. if(FALSE == SetEvent( g_hStopEvent ))
  274. {
  275. LogEvent( _T("Unable to signal Stop Event; Error: %ld"), GetLastError());
  276. }
  277. CloseHandle( g_hStopEvent );
  278. }
  279. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  280. break;
  281. case SERVICE_CONTROL_PAUSE:
  282. break;
  283. case SERVICE_CONTROL_CONTINUE:
  284. break;
  285. case SERVICE_CONTROL_INTERROGATE:
  286. break;
  287. case SERVICE_CONTROL_SHUTDOWN:
  288. break;
  289. default:
  290. LogEvent(_T("Bad service request"));
  291. }
  292. }
  293. void WINAPI CServiceModule::_ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
  294. {
  295. _Module.ServiceMain(dwArgc, lpszArgv);
  296. }
  297. void WINAPI CServiceModule::_Handler(DWORD dwOpcode)
  298. {
  299. _Module.Handler(dwOpcode);
  300. }
  301. void CServiceModule::SetServiceStatus(DWORD dwState)
  302. {
  303. m_status.dwCurrentState = dwState;
  304. ::SetServiceStatus(m_hServiceStatus, &m_status);
  305. }
  306. void CServiceModule::Run()
  307. {
  308. BYTE *byteVersionBuff;
  309. VS_FIXEDFILEINFO *pVersionInfo;
  310. UINT uLength;
  311. _Module.dwThreadID = GetCurrentThreadId();
  312. HRESULT hr = CoInitialize(NULL);
  313. // If you are running on NT 4.0 or higher you can use the following call
  314. // instead to make the EXE free threaded.
  315. // This means that calls come in on a random RPC thread
  316. // HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  317. _ASSERTE(SUCCEEDED(hr));
  318. // This provides a NULL DACL which will allow access to everyone.
  319. CSecurityDescriptor sd;
  320. sd.InitializeFromThreadToken();
  321. hr = CoInitializeSecurity(sd, -1, NULL, NULL,
  322. RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
  323. _ASSERTE(SUCCEEDED(hr));
  324. hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
  325. _ASSERTE(SUCCEEDED(hr));
  326. TCHAR szFilePath[_MAX_PATH];
  327. ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
  328. DWORD dwBufferSize = GetFileVersionInfoSize(szFilePath,0);
  329. byteVersionBuff = (BYTE*) malloc (dwBufferSize);
  330. GetFileVersionInfo(szFilePath,NULL,dwBufferSize,byteVersionBuff);
  331. VerQueryValue(byteVersionBuff,_T("\\"),(VOID **) &pVersionInfo, &uLength);
  332. LogEvent(_T("CentralFileMover service version: %d.%d.%d.%d Started."), HIWORD (pVersionInfo->dwFileVersionMS),LOWORD(pVersionInfo->dwFileVersionMS)
  333. ,HIWORD(pVersionInfo->dwFileVersionLS),LOWORD(pVersionInfo->dwFileVersionLS)) ;
  334. if (m_bService)
  335. SetServiceStatus(SERVICE_RUNNING);
  336. //
  337. // Execute Archive Service
  338. //
  339. try
  340. {
  341. FMMain();
  342. }
  343. catch(...)
  344. {
  345. LogEvent( _T("CentralFilemover Service CRASHED !!! "));
  346. }
  347. MSG msg;
  348. while (GetMessage(&msg, 0, 0, 0))
  349. DispatchMessage(&msg);
  350. _Module.RevokeClassObjects();
  351. CoUninitialize();
  352. }
  353. /////////////////////////////////////////////////////////////////////////////
  354. //
  355. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
  356. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  357. {
  358. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  359. _Module.Init(ObjectMap, hInstance, IDS_SERVICENAME, &LIBID_CENTRALFMSVCLib);
  360. _Module.m_bService = TRUE;
  361. TCHAR szTokens[] = _T("-/");
  362. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  363. while (lpszToken != NULL)
  364. {
  365. if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  366. return _Module.UnregisterServer();
  367. // Register as Local Server
  368. if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  369. return _Module.RegisterServer(TRUE, FALSE);
  370. // Register as Service
  371. if (lstrcmpi(lpszToken, _T("Service"))==0)
  372. return _Module.RegisterServer(TRUE, TRUE);
  373. lpszToken = FindOneOf(lpszToken, szTokens);
  374. }
  375. // Are we Service or Local Server
  376. CRegKey keyAppID;
  377. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
  378. if (lRes != ERROR_SUCCESS)
  379. return lRes;
  380. CRegKey key;
  381. lRes = key.Open(keyAppID, _T("{4E27CC20-0519-4E8C-BFF1-03C0F14DCDDA}"), KEY_READ);
  382. if (lRes != ERROR_SUCCESS)
  383. return lRes;
  384. TCHAR szValue[_MAX_PATH];
  385. DWORD dwLen = _MAX_PATH;
  386. lRes = key.QueryValue(szValue, _T("LocalService"), &dwLen);
  387. _Module.m_bService = FALSE;
  388. if (lRes == ERROR_SUCCESS)
  389. _Module.m_bService = TRUE;
  390. _Module.Start();
  391. // When we get here, the service has been stopped
  392. return _Module.m_status.dwWin32ExitCode;
  393. }
  394. BOOL CServiceModule::GetRegData(DWORD *Interval, TCHAR *SourceDir, TCHAR *ArchiveDir, TCHAR *MQConnectionString)
  395. {
  396. HKEY hHKLM;
  397. HKEY hArchiveKey;
  398. BYTE Buffer[MAX_PATH + 1];
  399. DWORD Type;
  400. DWORD BufferSize = MAX_PATH +1; // Set for largest value
  401. if(!RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hHKLM))
  402. {
  403. if(!RegOpenKeyEx(hHKLM,_T("Software\\Microsoft\\CentralFMService"), 0, KEY_ALL_ACCESS, &hArchiveKey))
  404. {
  405. // Get the input queue directory path
  406. if (RegQueryValueEx(hArchiveKey,_T("SourceDir"), 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  407. {
  408. LogEvent(_T("Failed to get InputQueue value from registry. Useing c:\\ as the default"));
  409. }
  410. else
  411. {
  412. _tcscpy (SourceDir, (TCHAR *) Buffer);
  413. BufferSize = MAX_PATH +1;
  414. ZeroMemory(Buffer, BufferSize);
  415. }
  416. // Now get the Win2kDSN
  417. RegQueryValueEx(hArchiveKey,_T("ArchiveDir"), 0, &Type, Buffer, &BufferSize);
  418. _tcscpy(ArchiveDir, (TCHAR *) Buffer);
  419. BufferSize = MAX_PATH +1;
  420. ZeroMemory(Buffer, BufferSize);
  421. // Now get the MSMQ Connection String
  422. RegQueryValueEx(hArchiveKey,_T("MQConnectionString"), 0, &Type, Buffer, &BufferSize);
  423. _tcscpy(MQConnectionString, (TCHAR *) Buffer);
  424. BufferSize = MAX_PATH +1;
  425. ZeroMemory(Buffer, BufferSize);
  426. // Get the sleep interval
  427. RegQueryValueEx(hArchiveKey,_T("Interval"), 0, &Type, Buffer, &BufferSize);
  428. *Interval = (DWORD)Buffer[0];
  429. RegCloseKey(hHKLM);
  430. RegCloseKey(hArchiveKey);
  431. return TRUE;
  432. }
  433. else
  434. { RegCloseKey(hHKLM);
  435. return FALSE;
  436. }
  437. }
  438. else
  439. return FALSE;
  440. }
  441. BOOL CServiceModule::FMMain()
  442. {
  443. HANDLE hFind = INVALID_HANDLE_VALUE;
  444. TCHAR SourceDir[MAX_PATH];
  445. TCHAR SearchPath[MAX_PATH];
  446. TCHAR ArchiveDir[MAX_PATH];
  447. TCHAR ArchivePath[MAX_PATH];
  448. TCHAR SourceFile[MAX_PATH];
  449. TCHAR MQConnectionString[MAX_PATH];
  450. WIN32_FIND_DATA FindData;
  451. DWORD Interval = 0;
  452. TCHAR CurrentDate[100];
  453. HRESULT hresult;
  454. HANDLE hStopEvent = NULL;
  455. SYSTEMTIME systime;
  456. QUEUEHANDLE hOutgoingQueue;
  457. BOOL OkToContinue = TRUE;
  458. const int NUMBEROFPROPERTIES = 5; // Number of properties.
  459. MQMSGPROPS msgProps;
  460. MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  461. MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  462. HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  463. DWORD cPropId = 0;
  464. ZeroMemory (&FindData, sizeof(WIN32_FIND_DATA));
  465. hStopEvent = OpenEvent(
  466. EVENT_ALL_ACCESS,
  467. FALSE,
  468. s_cszStopEvent
  469. );
  470. if (hStopEvent == NULL)
  471. {
  472. LogEvent(_T("Failed to open stop event"));
  473. goto done;
  474. }
  475. LogEvent(_T("Get Reg Data"));
  476. //Get reg Data
  477. GetRegData(&Interval, SourceDir, ArchiveDir, MQConnectionString);
  478. LogEvent (_T("Obtained reg data: Interval:%d SourceDir:%s ArchiveDir: %s"), Interval,SourceDir,ArchiveDir);
  479. // Connect to the queue
  480. // pqinfo->PathName = _T(".\\PRIVATE$\\FileQueue700");
  481. // pqinfo->ServiceTypeGuid=L"{c30e0960-a2c0-11cf-9785-00608cb3e80c}";
  482. //pqinfo->Create();
  483. hresult = MQOpenQueue(MQConnectionString,
  484. MQ_SEND_ACCESS,
  485. MQ_DENY_NONE,
  486. &hOutgoingQueue);
  487. if (FAILED(hresult))
  488. {
  489. LogEvent(_T("Unable to connect to message queue: %s"), MQConnectionString);
  490. }
  491. while (1)
  492. {
  493. // Build SearchPath
  494. _stprintf(SearchPath, _T("%s\\*.cab"), SourceDir);
  495. //Find file loop start
  496. hFind = FindFirstFile(SearchPath, &FindData);
  497. if (hFind != INVALID_HANDLE_VALUE)
  498. {
  499. do
  500. {
  501. if ( ! (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  502. {
  503. if(WAIT_OBJECT_0 == WaitForSingleObject( hStopEvent, 10))
  504. {
  505. FindClose(hFind);
  506. LogEvent( _T("Stop Event received. Terminating Central FM Service") );
  507. goto done;
  508. }
  509. //Get Current Date
  510. GetLocalTime(&systime);
  511. _stprintf(CurrentDate,_T("%0d-%0d-%0d"),systime.wMonth,systime.wDay,systime.wYear);
  512. _stprintf(SourceFile, _T("%s\\%s"), SourceDir, FindData.cFileName);
  513. //build archive path
  514. _stprintf (ArchivePath, _T("%s\\%s"), ArchiveDir, CurrentDate);
  515. if (!PathIsDirectory(ArchivePath))
  516. {
  517. CreateDirectory(ArchivePath,NULL);
  518. }
  519. _stprintf (ArchivePath, _T("%s\\%s\\%s"), ArchiveDir, CurrentDate, FindData.cFileName+2);
  520. //Move File to Archive Path
  521. if (CopyFile(SourceFile, ArchivePath, FALSE))
  522. {
  523. //Add file Path to MSMG
  524. ////////////////////////////////////////////////////////////
  525. // Send message.
  526. ////////////////////////////////////////////////////////////
  527. // Specify the message properties to be sent.
  528. aMsgPropId [cPropId] = PROPID_M_LABEL; // Property ID.
  529. aMsgPropVar[cPropId].vt = VT_LPWSTR; // Type indicator.
  530. aMsgPropVar[cPropId].pwszVal = L"FilePath"; // The message label.
  531. cPropId++;
  532. aMsgPropId [cPropId] = PROPID_M_BODY;
  533. aMsgPropVar [cPropId].vt = VT_VECTOR|VT_UI1;
  534. aMsgPropVar [cPropId].caub.pElems = (LPBYTE) ArchivePath;
  535. aMsgPropVar [cPropId].caub.cElems = wcslen(ArchivePath) * sizeof wchar_t;
  536. cPropId++;
  537. aMsgPropId [cPropId] = PROPID_M_BODY_TYPE;
  538. aMsgPropVar[cPropId].vt = VT_UI4;
  539. aMsgPropVar[cPropId].ulVal = (DWORD) VT_BSTR;
  540. cPropId++;
  541. // Initialize the MQMSGPROPS structure.
  542. msgProps.cProp = cPropId;
  543. msgProps.aPropID = aMsgPropId;
  544. msgProps.aPropVar = aMsgPropVar;
  545. msgProps.aStatus = aMsgStatus;
  546. // Send it
  547. hresult = MQSendMessage(
  548. hOutgoingQueue, // Queue handle.
  549. &msgProps, // Message property structure.
  550. MQ_NO_TRANSACTION // No transaction.
  551. );
  552. if (FAILED(hresult))
  553. {
  554. LogEvent(_T("Failed to send Message"));
  555. }
  556. ////////////////////////////////////////////////////////////
  557. // Close queue.
  558. ////////////////////////////////////////////////////////////
  559. // qSend->Close();
  560. // Delete the local file
  561. if (!DeleteFile(SourceFile))
  562. {
  563. LogEvent(_T("Unable to delete file: %s"), SourceFile);
  564. }
  565. }
  566. else
  567. {
  568. // The server is down what do we want to do here
  569. while (!OkToContinue)
  570. {
  571. LogEvent(_T("The Archive Path: %s is unreachable Sleeping for 1 minute."),ArchivePath);
  572. goto done;
  573. }
  574. }
  575. }
  576. }while (FindNextFile(hFind, &FindData));
  577. MQCloseQueue(hOutgoingQueue);
  578. FindClose(hFind);
  579. ZeroMemory (&FindData, sizeof(WIN32_FIND_DATA));
  580. }
  581. if(WAIT_OBJECT_0 == WaitForSingleObject( hStopEvent, Interval*60*1000))
  582. {
  583. FindClose(hFind);
  584. LogEvent( _T("Stop Event received. Terminating Central FM Service") );
  585. goto done;
  586. }
  587. //End File Loop
  588. }
  589. done:
  590. CloseHandle(hStopEvent);
  591. return TRUE;
  592. }