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.

3623 lines
123 KiB

  1. #include "faxsvc.h"
  2. #include "faxreg.h"
  3. #include "archive.h"
  4. static PROPSPEC const pspecFaxMessage[] =
  5. {
  6. {PRSPEC_PROPID, PID_FAX_CSID},
  7. {PRSPEC_PROPID, PID_FAX_TSID},
  8. {PRSPEC_PROPID, PID_FAX_PORT},
  9. {PRSPEC_PROPID, PID_FAX_ROUTING},
  10. {PRSPEC_PROPID, PID_FAX_CALLERID},
  11. {PRSPEC_PROPID, PID_FAX_DOCUMENT},
  12. {PRSPEC_PROPID, PID_FAX_SUBJECT},
  13. {PRSPEC_PROPID, PID_FAX_RETRIES},
  14. {PRSPEC_PROPID, PID_FAX_PRIORITY},
  15. {PRSPEC_PROPID, PID_FAX_PAGES},
  16. {PRSPEC_PROPID, PID_FAX_TYPE},
  17. {PRSPEC_PROPID, PID_FAX_START_TIME},
  18. {PRSPEC_PROPID, PID_FAX_END_TIME},
  19. {PRSPEC_PROPID, PID_FAX_SUBMISSION_TIME},
  20. {PRSPEC_PROPID, PID_FAX_ORIGINAL_SCHED_TIME},
  21. {PRSPEC_PROPID, PID_FAX_SENDER_USER_NAME},
  22. {PRSPEC_PROPID, PID_FAX_RECIP_NAME},
  23. {PRSPEC_PROPID, PID_FAX_RECIP_NUMBER},
  24. {PRSPEC_PROPID, PID_FAX_SENDER_NAME},
  25. {PRSPEC_PROPID, PID_FAX_SENDER_NUMBER},
  26. {PRSPEC_PROPID, PID_FAX_SENDER_BILLING},
  27. {PRSPEC_PROPID, PID_FAX_STATUS},
  28. {PRSPEC_PROPID, PID_FAX_STATUS_EX},
  29. {PRSPEC_PROPID, PID_FAX_STATUS_STR_EX},
  30. {PRSPEC_PROPID, PID_FAX_BROADCAST_ID}
  31. };
  32. #define FAX_MESSAGE_PROPERTIES (sizeof(pspecFaxMessage)/sizeof(pspecFaxMessage[0]))
  33. static PROPSPEC const pspecFaxRecipient[] =
  34. {
  35. {PRSPEC_PROPID, PID_FAX_RECIP_NAME},
  36. {PRSPEC_PROPID, PID_FAX_RECIP_NUMBER},
  37. {PRSPEC_PROPID, PID_FAX_RECIP_COMPANY},
  38. {PRSPEC_PROPID, PID_FAX_RECIP_STREET},
  39. {PRSPEC_PROPID, PID_FAX_RECIP_CITY},
  40. {PRSPEC_PROPID, PID_FAX_RECIP_STATE},
  41. {PRSPEC_PROPID, PID_FAX_RECIP_ZIP},
  42. {PRSPEC_PROPID, PID_FAX_RECIP_COUNTRY},
  43. {PRSPEC_PROPID, PID_FAX_RECIP_TITLE},
  44. {PRSPEC_PROPID, PID_FAX_RECIP_DEPARTMENT},
  45. {PRSPEC_PROPID, PID_FAX_RECIP_OFFICE_LOCATION},
  46. {PRSPEC_PROPID, PID_FAX_RECIP_HOME_PHONE},
  47. {PRSPEC_PROPID, PID_FAX_RECIP_OFFICE_PHONE},
  48. {PRSPEC_PROPID, PID_FAX_RECIP_EMAIL}
  49. };
  50. #define FAX_RECIP_PROPERTIES (sizeof(pspecFaxRecipient)/sizeof(pspecFaxRecipient[0]))
  51. static PROPSPEC const pspecFaxSender[] =
  52. {
  53. {PRSPEC_PROPID, PID_FAX_SENDER_BILLING},
  54. {PRSPEC_PROPID, PID_FAX_SENDER_NAME},
  55. {PRSPEC_PROPID, PID_FAX_SENDER_NUMBER},
  56. {PRSPEC_PROPID, PID_FAX_SENDER_COMPANY},
  57. {PRSPEC_PROPID, PID_FAX_SENDER_STREET},
  58. {PRSPEC_PROPID, PID_FAX_SENDER_CITY},
  59. {PRSPEC_PROPID, PID_FAX_SENDER_STATE},
  60. {PRSPEC_PROPID, PID_FAX_SENDER_ZIP},
  61. {PRSPEC_PROPID, PID_FAX_SENDER_COUNTRY},
  62. {PRSPEC_PROPID, PID_FAX_SENDER_TITLE},
  63. {PRSPEC_PROPID, PID_FAX_SENDER_DEPARTMENT},
  64. {PRSPEC_PROPID, PID_FAX_SENDER_OFFICE_LOCATION},
  65. {PRSPEC_PROPID, PID_FAX_SENDER_HOME_PHONE},
  66. {PRSPEC_PROPID, PID_FAX_SENDER_OFFICE_PHONE},
  67. {PRSPEC_PROPID, PID_FAX_SENDER_EMAIL},
  68. {PRSPEC_PROPID, PID_FAX_SENDER_TSID}
  69. };
  70. #define FAX_SENDER_PROPERTIES (sizeof(pspecFaxSender)/sizeof(pspecFaxSender[0]))
  71. #define MAX_FAX_PROPERTIES FAX_MESSAGE_PROPERTIES + FAX_RECIP_PROPERTIES + FAX_SENDER_PROPERTIES
  72. #define QUOTA_WARNING_TIME_OUT (1000*60*60*24) // 1 day,
  73. // The quota warning thread checks the archive size each QUOTA_WARNING_TIME_OUT
  74. #define QUOTA_REFRESH_COUNT 10 // Every QUOTA_REFRESH_COUNT the quota warning thread
  75. // recalculate the archive folder size using FindFirst, FindNext
  76. #define QUOTA_AUTO_DELETE_TIME_OUT (1000*60*60*24) // 1 day,
  77. // The quota auto delete thread deletes the archive old files each QUOTA_AUTO_DELETE_TIME_OUT
  78. FAX_QUOTA_WARN g_FaxQuotaWarn[2];
  79. HANDLE g_hArchiveQuotaWarningEvent;
  80. //*********************************************************************************
  81. //* Name: GetMessageMsTags()
  82. //* Author: Oded Sacher
  83. //* Date: Nov 8, 1999
  84. //*********************************************************************************
  85. //* DESCRIPTION:
  86. //* Fills FAX_MESSAGE structure.
  87. //* The caller must free all strings.
  88. //*
  89. //* PARAMETERS:
  90. //* [IN ] LPCTSTR lpctstrFileName
  91. //* pointer to the file name.
  92. //*
  93. //* [OUT] PFAX_MESSAGE pMessage
  94. //* The FAX_MESSAGE structure to be filled.
  95. //*
  96. //*
  97. //* RETURN VALUE:
  98. //* TRUE
  99. //* If no error occured.
  100. //* FALSE
  101. //* If an error occured.
  102. //*********************************************************************************
  103. BOOL GetMessageMsTags(
  104. LPCTSTR lpctstrFileName,
  105. PFAX_MESSAGE pMessage
  106. )
  107. {
  108. WORD NumDirEntries;
  109. HANDLE hFile = INVALID_HANDLE_VALUE;
  110. HANDLE hMap = NULL;
  111. LPBYTE fPtr = NULL;
  112. BOOL RetVal = FALSE;
  113. DEBUG_FUNCTION_NAME(TEXT("GetMessageMsTags"));
  114. PTIFF_TAG pTiffTags;
  115. DWORD i;
  116. DWORD PrevTagId;
  117. FAX_MESSAGE FaxMessage = {0};
  118. FILETIME FaxTime;
  119. DWORD ec = ERROR_SUCCESS;
  120. BOOL fUnMapTiff = FALSE;
  121. DWORD dwIfdOffset;
  122. Assert (pMessage != NULL);
  123. if (!MemoryMapTiffFile (lpctstrFileName, &FaxMessage.dwSize, &fPtr, &hFile, &hMap, &dwIfdOffset))
  124. {
  125. ec = GetLastError();
  126. DebugPrintEx( DEBUG_ERR,
  127. TEXT("MemoryMapTiffFile Failed, error: %ld"),
  128. ec);
  129. goto error_exit;
  130. }
  131. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_SIZE;
  132. //
  133. // get the count of tags in this IFD
  134. //
  135. NumDirEntries = *(LPWORD)(fPtr + dwIfdOffset);
  136. pTiffTags = (PTIFF_TAG)(fPtr + dwIfdOffset +sizeof(WORD));
  137. //
  138. // walk the tags and pick out the info we need
  139. //
  140. for (i = 0, PrevTagId = 0; i < NumDirEntries; i++) {
  141. //
  142. // verify that the tags are in ascending order
  143. //
  144. if (pTiffTags[i].TagId < PrevTagId) {
  145. DebugPrintEx( DEBUG_ERR, TEXT("File %s, Invalid TIFF format"), lpctstrFileName);
  146. ec = ERROR_BAD_FORMAT;
  147. goto error_exit;
  148. }
  149. PrevTagId = pTiffTags[i].TagId;
  150. switch( pTiffTags[i].TagId ) {
  151. case TIFFTAG_TYPE:
  152. FaxMessage.dwJobType = pTiffTags[i].DataOffset;
  153. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TYPE;
  154. break;
  155. case TIFFTAG_PAGES:
  156. FaxMessage.dwPageCount = pTiffTags[i].DataOffset;
  157. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_PAGE_COUNT;
  158. break;
  159. case TIFFTAG_PRIORITY:
  160. FaxMessage.Priority = (FAX_ENUM_PRIORITY_TYPE)pTiffTags[i].DataOffset;
  161. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_PRIORITY;
  162. break;
  163. case TIFFTAG_STATUS:
  164. FaxMessage.dwQueueStatus = pTiffTags[i].DataOffset;
  165. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_QUEUE_STATUS;
  166. break;
  167. case TIFFTAG_EXTENDED_STATUS:
  168. FaxMessage.dwExtendedStatus = pTiffTags[i].DataOffset;
  169. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_STATUS_EX;
  170. break;
  171. case TIFFTAG_EXTENDED_STATUS_TEXT:
  172. FaxMessage.lpctstrExtendedStatus = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  173. if (FaxMessage.lpctstrExtendedStatus == NULL)
  174. {
  175. ec = GetLastError();
  176. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  177. goto error_exit;
  178. }
  179. break;
  180. case TIFFTAG_BROADCAST_ID:
  181. if (!GetMsTagDwordLong(fPtr, FaxMessage.dwSize, &pTiffTags[i], &FaxMessage.dwlBroadcastId))
  182. {
  183. ec = GetLastError();
  184. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagDwordLong failed"));
  185. goto error_exit;
  186. }
  187. if(FaxMessage.dwlBroadcastId != 0)
  188. {
  189. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_BROADCAST_ID;
  190. }
  191. break;
  192. case TIFFTAG_RECIP_NUMBER:
  193. FaxMessage.lpctstrRecipientNumber = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  194. if (FaxMessage.lpctstrRecipientNumber == NULL)
  195. {
  196. ec = GetLastError();
  197. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  198. goto error_exit;
  199. }
  200. break;
  201. case TIFFTAG_RECIP_NAME:
  202. FaxMessage.lpctstrRecipientName = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  203. if (FaxMessage.lpctstrRecipientName == NULL)
  204. {
  205. ec = GetLastError();
  206. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  207. goto error_exit;
  208. }
  209. break;
  210. case TIFFTAG_TSID:
  211. FaxMessage.lpctstrTsid = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  212. if (FaxMessage.lpctstrTsid == NULL)
  213. {
  214. ec = GetLastError();
  215. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  216. goto error_exit;
  217. }
  218. break;
  219. case TIFFTAG_CSID:
  220. FaxMessage.lpctstrCsid = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  221. if (FaxMessage.lpctstrCsid == NULL)
  222. {
  223. ec = GetLastError();
  224. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  225. goto error_exit;
  226. }
  227. break;
  228. case TIFFTAG_SENDER_USER_NAME:
  229. FaxMessage.lpctstrSenderUserName = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  230. if (FaxMessage.lpctstrSenderUserName == NULL)
  231. {
  232. ec = GetLastError();
  233. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  234. goto error_exit;
  235. }
  236. break;
  237. case TIFFTAG_SENDER_BILLING:
  238. FaxMessage.lpctstrBillingCode = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  239. if (FaxMessage.lpctstrBillingCode == NULL)
  240. {
  241. ec = GetLastError();
  242. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  243. goto error_exit;
  244. }
  245. break;
  246. case TIFFTAG_FAX_START_TIME:
  247. if (!GetMsTagFileTime(fPtr, FaxMessage.dwSize, &pTiffTags[i], &FaxTime))
  248. {
  249. ec = GetLastError();
  250. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagFileTime failed"));
  251. goto error_exit;
  252. }
  253. if((DWORDLONG)0 != *(DWORDLONG*)&FaxTime)
  254. {
  255. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmTransmissionStartTime))
  256. {
  257. ec = GetLastError();
  258. DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToSystemTime failed"));
  259. goto error_exit;
  260. }
  261. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TRANSMISSION_START_TIME;
  262. }
  263. break;
  264. case TIFFTAG_FAX_END_TIME:
  265. if (!GetMsTagFileTime(fPtr, FaxMessage.dwSize, &pTiffTags[i], &FaxTime))
  266. {
  267. ec = GetLastError();
  268. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagFileTime failed"));
  269. goto error_exit;
  270. }
  271. if((DWORDLONG)0 != *(DWORDLONG*)&FaxTime)
  272. {
  273. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmTransmissionEndTime))
  274. {
  275. ec = GetLastError();
  276. DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToSystemTime failed"));
  277. goto error_exit;
  278. }
  279. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TRANSMISSION_END_TIME;
  280. }
  281. break;
  282. case TIFFTAG_FAX_SUBMISSION_TIME:
  283. if (!GetMsTagFileTime(fPtr, FaxMessage.dwSize, &pTiffTags[i], &FaxTime))
  284. {
  285. ec = GetLastError();
  286. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagFileTime failed"));
  287. goto error_exit;
  288. }
  289. if((DWORDLONG)0 != *(DWORDLONG*)&FaxTime)
  290. {
  291. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmSubmissionTime))
  292. {
  293. ec = GetLastError();
  294. DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToSystemTime failed"));
  295. goto error_exit;
  296. }
  297. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_SUBMISSION_TIME;
  298. }
  299. break;
  300. case TIFFTAG_FAX_SCHEDULED_TIME:
  301. if (!GetMsTagFileTime(fPtr, FaxMessage.dwSize, &pTiffTags[i], &FaxTime))
  302. {
  303. ec = GetLastError();
  304. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagFileTime failed"));
  305. goto error_exit;
  306. }
  307. if((DWORDLONG)0 != *(DWORDLONG*)&FaxTime)
  308. {
  309. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmOriginalScheduleTime))
  310. {
  311. ec = GetLastError();
  312. DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToSystemTime failed"));
  313. goto error_exit;
  314. }
  315. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_ORIGINAL_SCHEDULE_TIME;
  316. }
  317. break;
  318. case TIFFTAG_PORT:
  319. FaxMessage.lpctstrDeviceName = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  320. if (FaxMessage.lpctstrDeviceName == NULL)
  321. {
  322. ec = GetLastError();
  323. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  324. goto error_exit;
  325. }
  326. break;
  327. case TIFFTAG_RETRIES:
  328. FaxMessage.dwRetries = pTiffTags[i].DataOffset;
  329. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_RETRIES;
  330. break;
  331. case TIFFTAG_DOCUMENT:
  332. FaxMessage.lpctstrDocumentName = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  333. if (FaxMessage.lpctstrDocumentName == NULL)
  334. {
  335. ec = GetLastError();
  336. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  337. goto error_exit;
  338. }
  339. break;
  340. case TIFFTAG_SUBJECT:
  341. FaxMessage.lpctstrSubject = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  342. if (FaxMessage.lpctstrSubject == NULL)
  343. {
  344. ec = GetLastError();
  345. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  346. goto error_exit;
  347. }
  348. break;
  349. case TIFFTAG_CALLERID:
  350. FaxMessage.lpctstrCallerID = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  351. if (FaxMessage.lpctstrCallerID == NULL)
  352. {
  353. ec = GetLastError();
  354. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  355. goto error_exit;
  356. }
  357. break;
  358. case TIFFTAG_ROUTING:
  359. FaxMessage.lpctstrRoutingInfo = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  360. if (FaxMessage.lpctstrRoutingInfo == NULL)
  361. {
  362. ec = GetLastError();
  363. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  364. goto error_exit;
  365. }
  366. break;
  367. case TIFFTAG_SENDER_NAME:
  368. FaxMessage.lpctstrSenderName = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  369. if (FaxMessage.lpctstrSenderName == NULL)
  370. {
  371. ec = GetLastError();
  372. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  373. goto error_exit;
  374. }
  375. break;
  376. case TIFFTAG_SENDER_NUMBER:
  377. FaxMessage.lpctstrSenderNumber = GetMsTagString( fPtr, FaxMessage.dwSize, &pTiffTags[i]);
  378. if (FaxMessage.lpctstrSenderNumber == NULL)
  379. {
  380. ec = GetLastError();
  381. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  382. goto error_exit;
  383. }
  384. break;
  385. default:
  386. ;
  387. // There was an unknown tag (and it's ok,
  388. //cause we do not have to handle all the possible tags)
  389. }
  390. }
  391. //Get Unique JobId out of FileName
  392. if (!GetUniqueJobIdFromFileName( lpctstrFileName, &FaxMessage.dwlMessageId))
  393. {
  394. ec = ERROR_BAD_FORMAT;
  395. DebugPrintEx( DEBUG_ERR, TEXT("GetUniqueJobIdFromFileName Failed"));
  396. goto error_exit;
  397. }
  398. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_MESSAGE_ID;
  399. FaxMessage.dwSizeOfStruct = sizeof(FAX_MESSAGE);
  400. CopyMemory (pMessage, &FaxMessage, sizeof(FAX_MESSAGE));
  401. RetVal = TRUE;
  402. Assert (ec == ERROR_SUCCESS);
  403. error_exit:
  404. if (fPtr != NULL)
  405. {
  406. if (!UnmapViewOfFile( fPtr))
  407. {
  408. DebugPrintEx( DEBUG_ERR,
  409. TEXT("UnMapViewOfFile Failed, error: %d"),
  410. GetLastError());
  411. }
  412. }
  413. if (hMap != NULL)
  414. {
  415. CloseHandle( hMap );
  416. }
  417. if (hFile != INVALID_HANDLE_VALUE) {
  418. CloseHandle( hFile );
  419. }
  420. if (RetVal == FALSE)
  421. {
  422. MemFree((void*)FaxMessage.lpctstrExtendedStatus);
  423. MemFree((void*)FaxMessage.lpctstrRecipientNumber);
  424. MemFree((void*)FaxMessage.lpctstrRecipientName);
  425. MemFree((void*)FaxMessage.lpctstrTsid);
  426. MemFree((void*)FaxMessage.lpctstrCsid);
  427. MemFree((void*)FaxMessage.lpctstrSenderUserName);
  428. MemFree((void*)FaxMessage.lpctstrBillingCode);
  429. MemFree((void*)FaxMessage.lpctstrDeviceName);
  430. MemFree((void*)FaxMessage.lpctstrDocumentName);
  431. MemFree((void*)FaxMessage.lpctstrSubject);
  432. MemFree((void*)FaxMessage.lpctstrCallerID);
  433. MemFree((void*)FaxMessage.lpctstrRoutingInfo);
  434. MemFree((void*)FaxMessage.lpctstrSenderName);
  435. MemFree((void*)FaxMessage.lpctstrSenderNumber);
  436. Assert (ERROR_SUCCESS != ec);
  437. SetLastError(ec);
  438. }
  439. return RetVal;
  440. }
  441. //*********************************************************************************
  442. //* Name: GetFaxSenderMsTags()
  443. //* Author: Oded Sacher
  444. //* Date: Nov 8, 1999
  445. //*********************************************************************************
  446. //* DESCRIPTION:
  447. //* Fills PFAX_PERSONAL_PROFILE structure with sender information.
  448. //* The caller must free all strings.
  449. //*
  450. //* PARAMETERS:
  451. //* [IN ] LPCTSTR lpctstrFileName
  452. //* pointer to the file name.
  453. //*
  454. //* [OUT] PFAX_PERSONAL_PROFILE pPersonalProfile
  455. //* The PFAX_PERSONAL_PROFILE structure to be filled.
  456. //*
  457. //*
  458. //* RETURN VALUE:
  459. //* TRUE
  460. //* If no error occured.
  461. //* FALSE
  462. //* If an error occured.
  463. //*********************************************************************************
  464. BOOL GetFaxSenderMsTags(
  465. LPCTSTR lpctstrFileName,
  466. PFAX_PERSONAL_PROFILE pPersonalProfile
  467. )
  468. {
  469. WORD NumDirEntries;
  470. HANDLE hFile;
  471. HANDLE hMap = NULL;
  472. LPBYTE fPtr = NULL;
  473. BOOL RetVal = FALSE;
  474. DEBUG_FUNCTION_NAME(TEXT("GetFaxSenderMsTags"));
  475. PTIFF_TAG pTiffTags;
  476. DWORD i;
  477. DWORD PrevTagId;
  478. FAX_PERSONAL_PROFILE FaxPersonalProfile = {0};
  479. DWORD dwSize;
  480. DWORD ec = ERROR_SUCCESS;
  481. DWORD dwIfdOffset;
  482. Assert (pPersonalProfile != NULL);
  483. if (!MemoryMapTiffFile (lpctstrFileName, &dwSize, &fPtr, &hFile, &hMap, &dwIfdOffset))
  484. {
  485. ec = GetLastError();
  486. DebugPrintEx( DEBUG_ERR,
  487. TEXT("MemoryMapTiffFile Failed, error: %ld"),
  488. ec);
  489. goto error_exit;
  490. }
  491. //
  492. // get the count of tags in this IFD
  493. //
  494. NumDirEntries = *(LPWORD)(fPtr + dwIfdOffset);
  495. pTiffTags = (PTIFF_TAG)(fPtr + dwIfdOffset + sizeof(WORD));
  496. //
  497. // walk the tags and pick out the info we need
  498. //
  499. for (i = 0, PrevTagId = 0; i < NumDirEntries; i++) {
  500. //
  501. // verify that the tags are in ascending order
  502. //
  503. if (pTiffTags[i].TagId < PrevTagId) {
  504. DebugPrintEx( DEBUG_ERR, TEXT("File %s, Invalid TIFF format"), lpctstrFileName);
  505. goto error_exit;
  506. }
  507. PrevTagId = pTiffTags[i].TagId;
  508. switch( pTiffTags[i].TagId ) {
  509. case TIFFTAG_SENDER_NAME:
  510. FaxPersonalProfile.lptstrName = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  511. if (FaxPersonalProfile.lptstrName == NULL)
  512. {
  513. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  514. goto error_exit;
  515. }
  516. break;
  517. case TIFFTAG_SENDER_NUMBER:
  518. FaxPersonalProfile.lptstrFaxNumber = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  519. if (FaxPersonalProfile.lptstrFaxNumber == NULL)
  520. {
  521. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  522. goto error_exit;
  523. }
  524. break;
  525. case TIFFTAG_SENDER_COMPANY:
  526. FaxPersonalProfile.lptstrCompany = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  527. if (FaxPersonalProfile.lptstrCompany == NULL)
  528. {
  529. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  530. goto error_exit;
  531. }
  532. break;
  533. case TIFFTAG_SENDER_STREET:
  534. FaxPersonalProfile.lptstrStreetAddress = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  535. if (FaxPersonalProfile.lptstrStreetAddress == NULL)
  536. {
  537. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  538. goto error_exit;
  539. }
  540. break;
  541. case TIFFTAG_SENDER_CITY:
  542. FaxPersonalProfile.lptstrCity = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  543. if (FaxPersonalProfile.lptstrCity == NULL)
  544. {
  545. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  546. goto error_exit;
  547. }
  548. break;
  549. case TIFFTAG_SENDER_STATE:
  550. FaxPersonalProfile.lptstrState = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  551. if (FaxPersonalProfile.lptstrState == NULL)
  552. {
  553. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  554. goto error_exit;
  555. }
  556. break;
  557. case TIFFTAG_SENDER_ZIP:
  558. FaxPersonalProfile.lptstrZip = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  559. if (FaxPersonalProfile.lptstrZip == NULL)
  560. {
  561. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  562. goto error_exit;
  563. }
  564. break;
  565. case TIFFTAG_SENDER_COUNTRY:
  566. FaxPersonalProfile.lptstrCountry = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  567. if (FaxPersonalProfile.lptstrCountry == NULL)
  568. {
  569. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  570. goto error_exit;
  571. }
  572. break;
  573. case TIFFTAG_SENDER_TITLE:
  574. FaxPersonalProfile.lptstrTitle = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  575. if (FaxPersonalProfile.lptstrTitle == NULL)
  576. {
  577. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  578. goto error_exit;
  579. }
  580. break;
  581. case TIFFTAG_SENDER_DEPARTMENT:
  582. FaxPersonalProfile.lptstrDepartment = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  583. if (FaxPersonalProfile.lptstrDepartment == NULL)
  584. {
  585. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  586. goto error_exit;
  587. }
  588. break;
  589. case TIFFTAG_SENDER_OFFICE_LOCATION:
  590. FaxPersonalProfile.lptstrOfficeLocation = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  591. if (FaxPersonalProfile.lptstrOfficeLocation == NULL)
  592. {
  593. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  594. goto error_exit;
  595. }
  596. break;
  597. case TIFFTAG_SENDER_HOME_PHONE:
  598. FaxPersonalProfile.lptstrHomePhone = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  599. if (FaxPersonalProfile.lptstrHomePhone == NULL)
  600. {
  601. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  602. goto error_exit;
  603. }
  604. break;
  605. case TIFFTAG_SENDER_OFFICE_PHONE:
  606. FaxPersonalProfile.lptstrOfficePhone = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  607. if (FaxPersonalProfile.lptstrOfficePhone == NULL)
  608. {
  609. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  610. goto error_exit;
  611. }
  612. break;
  613. case TIFFTAG_SENDER_EMAIL:
  614. FaxPersonalProfile.lptstrEmail = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  615. if (FaxPersonalProfile.lptstrEmail == NULL)
  616. {
  617. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  618. goto error_exit;
  619. }
  620. break;
  621. case TIFFTAG_SENDER_BILLING:
  622. FaxPersonalProfile.lptstrBillingCode = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  623. if (FaxPersonalProfile.lptstrBillingCode == NULL)
  624. {
  625. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  626. goto error_exit;
  627. }
  628. break;
  629. case TIFFTAG_SENDER_TSID:
  630. FaxPersonalProfile.lptstrTSID = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  631. if (FaxPersonalProfile.lptstrTSID == NULL)
  632. {
  633. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  634. goto error_exit;
  635. }
  636. break;
  637. default:
  638. ;
  639. // There was an unknown tag (and it's ok,
  640. //cause we do not have to handle all the possible tags)
  641. }
  642. }
  643. FaxPersonalProfile.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  644. CopyMemory (pPersonalProfile, &FaxPersonalProfile, sizeof(FAX_PERSONAL_PROFILE));
  645. RetVal = TRUE;
  646. error_exit:
  647. if (fPtr != NULL)
  648. {
  649. if (!UnmapViewOfFile( fPtr))
  650. {
  651. DebugPrintEx( DEBUG_ERR,
  652. TEXT("UnMapViewOfFile Failed, error: %d"),
  653. GetLastError());
  654. }
  655. }
  656. if (hMap != NULL)
  657. {
  658. CloseHandle( hMap );
  659. }
  660. if (hFile != INVALID_HANDLE_VALUE) {
  661. CloseHandle( hFile );
  662. }
  663. if (RetVal == FALSE)
  664. {
  665. FreePersonalProfile (&FaxPersonalProfile, FALSE);
  666. }
  667. return RetVal;
  668. }
  669. //*********************************************************************************
  670. //* Name: GetFaxRecipientMsTags()
  671. //* Author: Oded Sacher
  672. //* Date: Nov 8, 1999
  673. //*********************************************************************************
  674. //* DESCRIPTION:
  675. //* Fills PFAX_PERSONAL_PROFILE structure with recipient information.
  676. //* The caller must free all strings.
  677. //*
  678. //* PARAMETERS:
  679. //* [IN ] LPCTSTR lpctstrFileName
  680. //* pointer to the file name.
  681. //*
  682. //* [OUT] PFAX_PERSONAL_PROFILE pPersonalProfile
  683. //* The PFAX_PERSONAL_PROFILE structure to be filled.
  684. //*
  685. //*
  686. //* RETURN VALUE:
  687. //* TRUE
  688. //* If no error occured.
  689. //* FALSE
  690. //* If an error occured.
  691. //*********************************************************************************
  692. BOOL GetFaxRecipientMsTags(
  693. LPCTSTR lpctstrFileName,
  694. PFAX_PERSONAL_PROFILE pPersonalProfile
  695. )
  696. {
  697. WORD NumDirEntries;
  698. HANDLE hFile;
  699. HANDLE hMap = NULL;
  700. LPBYTE fPtr = NULL;
  701. BOOL RetVal = FALSE;
  702. DEBUG_FUNCTION_NAME(TEXT("GetRecipientMsTags"));
  703. PTIFF_TAG pTiffTags;
  704. DWORD i;
  705. DWORD PrevTagId;
  706. FAX_PERSONAL_PROFILE FaxPersonalProfile = {0};
  707. DWORD dwSize;
  708. DWORD ec = ERROR_SUCCESS;
  709. DWORD dwIfdOffset;
  710. Assert (pPersonalProfile != NULL);
  711. if (!MemoryMapTiffFile (lpctstrFileName, &dwSize, &fPtr, &hFile, &hMap, &dwIfdOffset))
  712. {
  713. ec = GetLastError();
  714. DebugPrintEx( DEBUG_ERR,
  715. TEXT("MemoryMapTiffFile Failed, error: %ld"),
  716. ec);
  717. goto error_exit;
  718. }
  719. //
  720. // get the count of tags in this IFD
  721. //
  722. NumDirEntries = *(LPWORD)(fPtr + dwIfdOffset);
  723. pTiffTags = (PTIFF_TAG)(fPtr + dwIfdOffset + sizeof(WORD));
  724. //
  725. // walk the tags and pick out the info we need
  726. //
  727. for (i = 0, PrevTagId = 0; i < NumDirEntries; i++) {
  728. //
  729. // verify that the tags are in ascending order
  730. //
  731. if (pTiffTags[i].TagId < PrevTagId) {
  732. DebugPrintEx( DEBUG_ERR, TEXT("File %s, Invalid TIFF format"), lpctstrFileName);
  733. goto error_exit;
  734. }
  735. PrevTagId = pTiffTags[i].TagId;
  736. switch( pTiffTags[i].TagId ) {
  737. case TIFFTAG_RECIP_NAME:
  738. FaxPersonalProfile.lptstrName = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  739. if (FaxPersonalProfile.lptstrName == NULL)
  740. {
  741. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  742. goto error_exit;
  743. }
  744. break;
  745. case TIFFTAG_RECIP_NUMBER:
  746. FaxPersonalProfile.lptstrFaxNumber = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  747. if (FaxPersonalProfile.lptstrFaxNumber == NULL)
  748. {
  749. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  750. goto error_exit;
  751. }
  752. break;
  753. case TIFFTAG_RECIP_COMPANY:
  754. FaxPersonalProfile.lptstrCompany = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  755. if (FaxPersonalProfile.lptstrCompany == NULL)
  756. {
  757. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  758. goto error_exit;
  759. }
  760. break;
  761. case TIFFTAG_RECIP_STREET:
  762. FaxPersonalProfile.lptstrStreetAddress = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  763. if (FaxPersonalProfile.lptstrStreetAddress == NULL)
  764. {
  765. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  766. goto error_exit;
  767. }
  768. break;
  769. case TIFFTAG_RECIP_CITY:
  770. FaxPersonalProfile.lptstrCity = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  771. if (FaxPersonalProfile.lptstrCity == NULL)
  772. {
  773. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  774. goto error_exit;
  775. }
  776. break;
  777. case TIFFTAG_RECIP_STATE:
  778. FaxPersonalProfile.lptstrState = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  779. if (FaxPersonalProfile.lptstrState == NULL)
  780. {
  781. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  782. goto error_exit;
  783. }
  784. break;
  785. case TIFFTAG_RECIP_ZIP:
  786. FaxPersonalProfile.lptstrZip = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  787. if (FaxPersonalProfile.lptstrZip == NULL)
  788. {
  789. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  790. goto error_exit;
  791. }
  792. break;
  793. case TIFFTAG_RECIP_COUNTRY:
  794. FaxPersonalProfile.lptstrCountry = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  795. if (FaxPersonalProfile.lptstrCountry == NULL)
  796. {
  797. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  798. goto error_exit;
  799. }
  800. break;
  801. case TIFFTAG_RECIP_TITLE:
  802. FaxPersonalProfile.lptstrTitle = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  803. if (FaxPersonalProfile.lptstrTitle == NULL)
  804. {
  805. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  806. goto error_exit;
  807. }
  808. break;
  809. case TIFFTAG_RECIP_DEPARTMENT:
  810. FaxPersonalProfile.lptstrDepartment = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  811. if (FaxPersonalProfile.lptstrDepartment == NULL)
  812. {
  813. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  814. goto error_exit;
  815. }
  816. break;
  817. case TIFFTAG_RECIP_OFFICE_LOCATION:
  818. FaxPersonalProfile.lptstrOfficeLocation = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  819. if (FaxPersonalProfile.lptstrOfficeLocation == NULL)
  820. {
  821. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  822. goto error_exit;
  823. }
  824. break;
  825. case TIFFTAG_RECIP_HOME_PHONE:
  826. FaxPersonalProfile.lptstrHomePhone = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  827. if (FaxPersonalProfile.lptstrHomePhone == NULL)
  828. {
  829. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  830. goto error_exit;
  831. }
  832. break;
  833. case TIFFTAG_RECIP_OFFICE_PHONE:
  834. FaxPersonalProfile.lptstrOfficePhone = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  835. if (FaxPersonalProfile.lptstrOfficePhone == NULL)
  836. {
  837. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  838. goto error_exit;
  839. }
  840. break;
  841. case TIFFTAG_RECIP_EMAIL:
  842. FaxPersonalProfile.lptstrEmail = GetMsTagString( fPtr, dwSize, &pTiffTags[i]);
  843. if (FaxPersonalProfile.lptstrEmail == NULL)
  844. {
  845. DebugPrintEx( DEBUG_ERR, TEXT("GetMsTagString failed"));
  846. goto error_exit;
  847. }
  848. break;
  849. default:
  850. ;
  851. // There was an unknown tag (and it's ok,
  852. //cause we do not have to handle all the possible tags)
  853. }
  854. }
  855. FaxPersonalProfile.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  856. CopyMemory (pPersonalProfile, &FaxPersonalProfile, sizeof(FAX_PERSONAL_PROFILE));
  857. RetVal = TRUE;
  858. error_exit:
  859. if (fPtr != NULL)
  860. {
  861. if (!UnmapViewOfFile( fPtr))
  862. {
  863. DebugPrintEx( DEBUG_ERR,
  864. TEXT("UnMapViewOfFile Failed, error: %d"),
  865. GetLastError());
  866. }
  867. }
  868. if (hMap != NULL)
  869. {
  870. CloseHandle( hMap );
  871. }
  872. if (hFile != INVALID_HANDLE_VALUE) {
  873. CloseHandle( hFile );
  874. }
  875. if (RetVal == FALSE)
  876. {
  877. FreePersonalProfile (&FaxPersonalProfile, FALSE);
  878. }
  879. return RetVal;
  880. }
  881. //*********************************************************************************
  882. //* Name: AddNTFSStorageProperties()
  883. //* Author: Oded Sacher
  884. //* Date: Nov 8, 1999
  885. //*********************************************************************************
  886. //* DESCRIPTION:
  887. //* Adds NTFS Properties to a file
  888. //*
  889. //* PARAMETERS:
  890. //* [IN ] LPTSTR FileName
  891. //* pointer to the file name.
  892. //*
  893. //* [IN ] PMS_TAG_INFO MsTagInfo
  894. //* pointer to a structure containing all info to be written.
  895. //*
  896. //*
  897. //* [IN ] BOOL fSendJob
  898. //* Flag that indicates an outbound job.
  899. //*
  900. //*
  901. //* RETURN VALUE:
  902. //* TRUE
  903. //* If no error occured.
  904. //* FALSE
  905. //* If an error occured.
  906. //*********************************************************************************
  907. BOOL
  908. AddNTFSStorageProperties(
  909. LPTSTR FileName,
  910. PMS_TAG_INFO MsTagInfo,
  911. BOOL fSendJob
  912. )
  913. {
  914. HRESULT hr;
  915. IPropertySetStorage* pPropertySetStorage = NULL;
  916. IPropertyStorage* pPropertyStorage = NULL;
  917. PROPSPEC rgpspec[MAX_FAX_PROPERTIES];
  918. PROPVARIANT rgvar [MAX_FAX_PROPERTIES];
  919. DWORD i;
  920. DEBUG_FUNCTION_NAME(TEXT("AddNTFSStorageProperties"));
  921. BOOL RetVal = FALSE;
  922. DWORD ec = ERROR_SUCCESS;
  923. for (i = 0; i < MAX_FAX_PROPERTIES; i++)
  924. {
  925. PropVariantInit (&rgvar[i]);
  926. }
  927. hr = StgOpenStorageEx( FileName, //Points to path of compound file to create
  928. STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT,//Specifies the access mode for opening the storage object
  929. STGFMT_FILE, //Specifies the storage file format
  930. 0, //Reserved; must be zero
  931. NULL, //Points to STGOPTIONS structure which specifies features of the storage object
  932. 0, //Reserved; must be zero
  933. IID_IPropertySetStorage ,//Specifies the GUID of the interface pointer
  934. (void**)&pPropertySetStorage //Address of an interface pointer
  935. );
  936. if (FAILED(hr))
  937. {
  938. DebugPrintEx( DEBUG_ERR,TEXT("StgOpenStorageEx Failed, err : 0x%08X"), hr);
  939. ec = ERROR_OPEN_FAILED;
  940. goto exit;
  941. }
  942. hr = pPropertySetStorage->Create( FMTID_FaxProperties, //Format identifier of the property set to be created
  943. NULL, //Pointer to initial CLSID for this property set
  944. PROPSETFLAG_DEFAULT, //PROPSETFLAG values
  945. STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT, //Storage mode of new property set
  946. &pPropertyStorage //Address of output variable that receivesthe IPropertyStorage interface pointer
  947. );
  948. if (FAILED(hr))
  949. {
  950. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::Create Failed, err : 0x%08X"), hr);
  951. ec = ERROR_OPEN_FAILED;
  952. goto exit;
  953. }
  954. //
  955. // write out the data
  956. //
  957. i = 0;
  958. if (MsTagInfo->Csid) {
  959. rgpspec[i].ulKind = PRSPEC_PROPID;
  960. rgpspec[i].propid = PID_FAX_CSID;
  961. rgvar[i].vt = VT_LPWSTR;
  962. rgvar[i].pwszVal = MsTagInfo->Csid;
  963. i++;
  964. }
  965. if (MsTagInfo->Tsid) {
  966. rgpspec[i].ulKind = PRSPEC_PROPID;
  967. rgpspec[i].propid = PID_FAX_TSID;
  968. rgvar[i].vt = VT_LPWSTR;
  969. rgvar[i].pwszVal = MsTagInfo->Tsid;
  970. i++;
  971. }
  972. if (MsTagInfo->Port) {
  973. rgpspec[i].ulKind = PRSPEC_PROPID;
  974. rgpspec[i].propid = PID_FAX_PORT;
  975. rgvar[i].vt = VT_LPWSTR;
  976. rgvar[i].pwszVal = MsTagInfo->Port;
  977. i++;
  978. }
  979. if (fSendJob == FALSE)
  980. {
  981. // Receive job
  982. if (MsTagInfo->Routing) {
  983. rgpspec[i].ulKind = PRSPEC_PROPID;
  984. rgpspec[i].propid = PID_FAX_ROUTING;
  985. rgvar[i].vt = VT_LPWSTR;
  986. rgvar[i].pwszVal = MsTagInfo->Routing;
  987. i++;
  988. }
  989. if (MsTagInfo->CallerId) {
  990. rgpspec[i].ulKind = PRSPEC_PROPID;
  991. rgpspec[i].propid = PID_FAX_CALLERID;
  992. rgvar[i].vt = VT_LPWSTR;
  993. rgvar[i].pwszVal = MsTagInfo->CallerId;
  994. i++;
  995. }
  996. }
  997. else
  998. {
  999. // Send job
  1000. if (MsTagInfo->RecipName) {
  1001. rgpspec[i].ulKind = PRSPEC_PROPID;
  1002. rgpspec[i].propid = PID_FAX_RECIP_NAME;
  1003. rgvar[i].vt = VT_LPWSTR;
  1004. rgvar[i].pwszVal = MsTagInfo->RecipName;
  1005. i++;
  1006. }
  1007. if (MsTagInfo->RecipNumber) {
  1008. rgpspec[i].ulKind = PRSPEC_PROPID;
  1009. rgpspec[i].propid = PID_FAX_RECIP_NUMBER;
  1010. rgvar[i].vt = VT_LPWSTR;
  1011. rgvar[i].pwszVal = MsTagInfo->RecipNumber;
  1012. i++;
  1013. }
  1014. if (MsTagInfo->RecipCompany) {
  1015. rgpspec[i].ulKind = PRSPEC_PROPID;
  1016. rgpspec[i].propid = PID_FAX_RECIP_COMPANY;
  1017. rgvar[i].vt = VT_LPWSTR;
  1018. rgvar[i].pwszVal = MsTagInfo->RecipCompany;
  1019. i++;
  1020. }
  1021. if (MsTagInfo->RecipStreet) {
  1022. rgpspec[i].ulKind = PRSPEC_PROPID;
  1023. rgpspec[i].propid = PID_FAX_RECIP_STREET;
  1024. rgvar[i].vt = VT_LPWSTR;
  1025. rgvar[i].pwszVal = MsTagInfo->RecipStreet;
  1026. i++;
  1027. }
  1028. if (MsTagInfo->RecipCity) {
  1029. rgpspec[i].ulKind = PRSPEC_PROPID;
  1030. rgpspec[i].propid = PID_FAX_RECIP_CITY;
  1031. rgvar[i].vt = VT_LPWSTR;
  1032. rgvar[i].pwszVal = MsTagInfo->RecipCity;
  1033. i++;
  1034. }
  1035. if (MsTagInfo->RecipState) {
  1036. rgpspec[i].ulKind = PRSPEC_PROPID;
  1037. rgpspec[i].propid = PID_FAX_RECIP_STATE;
  1038. rgvar[i].vt = VT_LPWSTR;
  1039. rgvar[i].pwszVal = MsTagInfo->RecipState;
  1040. i++;
  1041. }
  1042. if (MsTagInfo->RecipZip) {
  1043. rgpspec[i].ulKind = PRSPEC_PROPID;
  1044. rgpspec[i].propid = PID_FAX_RECIP_ZIP;
  1045. rgvar[i].vt = VT_LPWSTR;
  1046. rgvar[i].pwszVal = MsTagInfo->RecipZip;
  1047. i++;
  1048. }
  1049. if (MsTagInfo->RecipCountry) {
  1050. rgpspec[i].ulKind = PRSPEC_PROPID;
  1051. rgpspec[i].propid = PID_FAX_RECIP_COUNTRY;
  1052. rgvar[i].vt = VT_LPWSTR;
  1053. rgvar[i].pwszVal = MsTagInfo->RecipCountry;
  1054. i++;
  1055. }
  1056. if (MsTagInfo->RecipTitle) {
  1057. rgpspec[i].ulKind = PRSPEC_PROPID;
  1058. rgpspec[i].propid = PID_FAX_RECIP_TITLE;
  1059. rgvar[i].vt = VT_LPWSTR;
  1060. rgvar[i].pwszVal = MsTagInfo->RecipTitle;
  1061. i++;
  1062. }
  1063. if (MsTagInfo->RecipDepartment) {
  1064. rgpspec[i].ulKind = PRSPEC_PROPID;
  1065. rgpspec[i].propid = PID_FAX_RECIP_DEPARTMENT;
  1066. rgvar[i].vt = VT_LPWSTR;
  1067. rgvar[i].pwszVal = MsTagInfo->RecipDepartment;
  1068. i++;
  1069. }
  1070. if (MsTagInfo->RecipOfficeLocation) {
  1071. rgpspec[i].ulKind = PRSPEC_PROPID;
  1072. rgpspec[i].propid = PID_FAX_RECIP_OFFICE_LOCATION;
  1073. rgvar[i].vt = VT_LPWSTR;
  1074. rgvar[i].pwszVal = MsTagInfo->RecipOfficeLocation;
  1075. i++;
  1076. }
  1077. if (MsTagInfo->RecipHomePhone) {
  1078. rgpspec[i].ulKind = PRSPEC_PROPID;
  1079. rgpspec[i].propid = PID_FAX_RECIP_HOME_PHONE;
  1080. rgvar[i].vt = VT_LPWSTR;
  1081. rgvar[i].pwszVal = MsTagInfo->RecipHomePhone;
  1082. i++;
  1083. }
  1084. if (MsTagInfo->RecipOfficePhone) {
  1085. rgpspec[i].ulKind = PRSPEC_PROPID;
  1086. rgpspec[i].propid = PID_FAX_RECIP_OFFICE_PHONE;
  1087. rgvar[i].vt = VT_LPWSTR;
  1088. rgvar[i].pwszVal = MsTagInfo->RecipOfficePhone;
  1089. i++;
  1090. }
  1091. if (MsTagInfo->RecipEMail) {
  1092. rgpspec[i].ulKind = PRSPEC_PROPID;
  1093. rgpspec[i].propid = PID_FAX_RECIP_EMAIL;
  1094. rgvar[i].vt = VT_LPWSTR;
  1095. rgvar[i].pwszVal = MsTagInfo->RecipEMail;
  1096. i++;
  1097. }
  1098. if (MsTagInfo-> SenderName) {
  1099. rgpspec[i].ulKind = PRSPEC_PROPID;
  1100. rgpspec[i].propid = PID_FAX_SENDER_NAME;
  1101. rgvar[i].vt = VT_LPWSTR;
  1102. rgvar[i].pwszVal = MsTagInfo->SenderName;
  1103. i++;
  1104. }
  1105. if (MsTagInfo-> SenderNumber) {
  1106. rgpspec[i].ulKind = PRSPEC_PROPID;
  1107. rgpspec[i].propid = PID_FAX_SENDER_NUMBER;
  1108. rgvar[i].vt = VT_LPWSTR;
  1109. rgvar[i].pwszVal = MsTagInfo->SenderNumber;
  1110. i++;
  1111. }
  1112. if (MsTagInfo-> SenderCompany) {
  1113. rgpspec[i].ulKind = PRSPEC_PROPID;
  1114. rgpspec[i].propid = PID_FAX_SENDER_COMPANY;
  1115. rgvar[i].vt = VT_LPWSTR;
  1116. rgvar[i].pwszVal = MsTagInfo->SenderCompany;
  1117. i++;
  1118. }
  1119. if (MsTagInfo-> SenderStreet) {
  1120. rgpspec[i].ulKind = PRSPEC_PROPID;
  1121. rgpspec[i].propid = PID_FAX_SENDER_STREET;
  1122. rgvar[i].vt = VT_LPWSTR;
  1123. rgvar[i].pwszVal = MsTagInfo->SenderStreet;
  1124. i++;
  1125. }
  1126. if (MsTagInfo-> SenderCity) {
  1127. rgpspec[i].ulKind = PRSPEC_PROPID;
  1128. rgpspec[i].propid = PID_FAX_SENDER_CITY;
  1129. rgvar[i].vt = VT_LPWSTR;
  1130. rgvar[i].pwszVal = MsTagInfo->SenderCity;
  1131. i++;
  1132. }
  1133. if (MsTagInfo-> SenderState) {
  1134. rgpspec[i].ulKind = PRSPEC_PROPID;
  1135. rgpspec[i].propid = PID_FAX_SENDER_STATE;
  1136. rgvar[i].vt = VT_LPWSTR;
  1137. rgvar[i].pwszVal = MsTagInfo->SenderState;
  1138. i++;
  1139. }
  1140. if (MsTagInfo-> SenderZip) {
  1141. rgpspec[i].ulKind = PRSPEC_PROPID;
  1142. rgpspec[i].propid = PID_FAX_SENDER_ZIP;
  1143. rgvar[i].vt = VT_LPWSTR;
  1144. rgvar[i].pwszVal = MsTagInfo->SenderZip;
  1145. i++;
  1146. }
  1147. if (MsTagInfo-> SenderCountry) {
  1148. rgpspec[i].ulKind = PRSPEC_PROPID;
  1149. rgpspec[i].propid = PID_FAX_SENDER_COUNTRY;
  1150. rgvar[i].vt = VT_LPWSTR;
  1151. rgvar[i].pwszVal = MsTagInfo->SenderCountry;
  1152. i++;
  1153. }
  1154. if (MsTagInfo-> SenderTitle) {
  1155. rgpspec[i].ulKind = PRSPEC_PROPID;
  1156. rgpspec[i].propid = PID_FAX_SENDER_TITLE;
  1157. rgvar[i].vt = VT_LPWSTR;
  1158. rgvar[i].pwszVal = MsTagInfo->SenderTitle;
  1159. i++;
  1160. }
  1161. if (MsTagInfo-> SenderDepartment) {
  1162. rgpspec[i].ulKind = PRSPEC_PROPID;
  1163. rgpspec[i].propid = PID_FAX_SENDER_DEPARTMENT;
  1164. rgvar[i].vt = VT_LPWSTR;
  1165. rgvar[i].pwszVal = MsTagInfo->SenderDepartment;
  1166. i++;
  1167. }
  1168. if (MsTagInfo-> SenderOfficeLocation) {
  1169. rgpspec[i].ulKind = PRSPEC_PROPID;
  1170. rgpspec[i].propid = PID_FAX_SENDER_OFFICE_LOCATION;
  1171. rgvar[i].vt = VT_LPWSTR;
  1172. rgvar[i].pwszVal = MsTagInfo->SenderOfficeLocation;
  1173. i++;
  1174. }
  1175. if (MsTagInfo-> SenderHomePhone) {
  1176. rgpspec[i].ulKind = PRSPEC_PROPID;
  1177. rgpspec[i].propid = PID_FAX_SENDER_HOME_PHONE;
  1178. rgvar[i].vt = VT_LPWSTR;
  1179. rgvar[i].pwszVal = MsTagInfo->SenderHomePhone;
  1180. i++;
  1181. }
  1182. if (MsTagInfo-> SenderOfficePhone) {
  1183. rgpspec[i].ulKind = PRSPEC_PROPID;
  1184. rgpspec[i].propid = PID_FAX_SENDER_OFFICE_PHONE;
  1185. rgvar[i].vt = VT_LPWSTR;
  1186. rgvar[i].pwszVal = MsTagInfo->SenderOfficePhone;
  1187. i++;
  1188. }
  1189. if (MsTagInfo-> SenderEMail) {
  1190. rgpspec[i].ulKind = PRSPEC_PROPID;
  1191. rgpspec[i].propid = PID_FAX_SENDER_EMAIL;
  1192. rgvar[i].vt = VT_LPWSTR;
  1193. rgvar[i].pwszVal = MsTagInfo->SenderEMail;
  1194. i++;
  1195. }
  1196. if (MsTagInfo->SenderBilling) {
  1197. rgpspec[i].ulKind = PRSPEC_PROPID;
  1198. rgpspec[i].propid = PID_FAX_SENDER_BILLING;
  1199. rgvar[i].vt = VT_LPWSTR;
  1200. rgvar[i].pwszVal = MsTagInfo->SenderBilling;
  1201. i++;
  1202. }
  1203. if (MsTagInfo->SenderUserName) {
  1204. rgpspec[i].ulKind = PRSPEC_PROPID;
  1205. rgpspec[i].propid = PID_FAX_SENDER_USER_NAME;
  1206. rgvar[i].vt = VT_LPWSTR;
  1207. rgvar[i].pwszVal = MsTagInfo->SenderUserName;
  1208. i++;
  1209. }
  1210. if (MsTagInfo->SenderTsid) {
  1211. rgpspec[i].ulKind = PRSPEC_PROPID;
  1212. rgpspec[i].propid = PID_FAX_SENDER_TSID;
  1213. rgvar[i].vt = VT_LPWSTR;
  1214. rgvar[i].pwszVal = MsTagInfo->SenderTsid;
  1215. i++;
  1216. }
  1217. if (MsTagInfo->Document) {
  1218. rgpspec[i].ulKind = PRSPEC_PROPID;
  1219. rgpspec[i].propid = PID_FAX_DOCUMENT;
  1220. rgvar[i].vt = VT_LPWSTR;
  1221. rgvar[i].pwszVal = MsTagInfo->Document;
  1222. i++;
  1223. }
  1224. if (MsTagInfo->Subject) {
  1225. rgpspec[i].ulKind = PRSPEC_PROPID;
  1226. rgpspec[i].propid = PID_FAX_SUBJECT;
  1227. rgvar[i].vt = VT_LPWSTR;
  1228. rgvar[i].pwszVal = MsTagInfo->Subject;
  1229. i++;
  1230. }
  1231. // Deal with Retries
  1232. rgpspec[i].ulKind = PRSPEC_PROPID;
  1233. rgpspec[i].propid = PID_FAX_RETRIES;
  1234. rgvar[i].vt = VT_UI4;
  1235. rgvar[i].ulVal = MsTagInfo->Retries;
  1236. i++;
  1237. // Deal with Priority
  1238. rgpspec[i].ulKind = PRSPEC_PROPID;
  1239. rgpspec[i].propid = PID_FAX_PRIORITY;
  1240. rgvar[i].vt = VT_UI4;
  1241. rgvar[i].ulVal = MsTagInfo->Priority;
  1242. i++;
  1243. // Deal with Submission time
  1244. Assert (MsTagInfo->SubmissionTime != 0);
  1245. rgpspec[i].ulKind = PRSPEC_PROPID;
  1246. rgpspec[i].propid = PID_FAX_SUBMISSION_TIME;
  1247. rgvar[i].vt = VT_FILETIME;
  1248. rgvar[i].filetime = *(FILETIME*)&MsTagInfo->SubmissionTime;
  1249. i++;
  1250. // Deal with Originaly scheduled time
  1251. Assert (MsTagInfo->OriginalScheduledTime);
  1252. rgpspec[i].ulKind = PRSPEC_PROPID;
  1253. rgpspec[i].propid = PID_FAX_ORIGINAL_SCHED_TIME;
  1254. rgvar[i].vt = VT_FILETIME;
  1255. rgvar[i].filetime = *(FILETIME*)&MsTagInfo->OriginalScheduledTime;
  1256. i++;
  1257. // Deal with Broadcast id
  1258. Assert (MsTagInfo->dwlBroadcastId != 0);
  1259. rgpspec[i].ulKind = PRSPEC_PROPID;
  1260. rgpspec[i].propid = PID_FAX_BROADCAST_ID;
  1261. rgvar[i].vt = VT_UI8;
  1262. rgvar[i].uhVal = *(ULARGE_INTEGER*)&MsTagInfo->dwlBroadcastId;
  1263. i++;
  1264. }
  1265. // Deal with Pages
  1266. rgpspec[i].ulKind = PRSPEC_PROPID;
  1267. rgpspec[i].propid = PID_FAX_PAGES;
  1268. rgvar[i].vt = VT_UI4;
  1269. rgvar[i].ulVal = MsTagInfo->Pages;
  1270. i++;
  1271. // Deal with Type
  1272. rgpspec[i].ulKind = PRSPEC_PROPID;
  1273. rgpspec[i].propid = PID_FAX_TYPE;
  1274. rgvar[i].vt = VT_UI4;
  1275. rgvar[i].ulVal = MsTagInfo->Type;
  1276. i++;
  1277. // Deal with Status
  1278. if (MsTagInfo->dwStatus == JS_COMPLETED) {
  1279. rgpspec[i].ulKind = PRSPEC_PROPID;
  1280. rgpspec[i].propid = PID_FAX_STATUS;
  1281. rgvar[i].vt = VT_UI4;
  1282. rgvar[i].ulVal = MsTagInfo->dwStatus;
  1283. i++;
  1284. }
  1285. // Deal with Extended status
  1286. if (MsTagInfo->dwExtendedStatus) {
  1287. rgpspec[i].ulKind = PRSPEC_PROPID;
  1288. rgpspec[i].propid = PID_FAX_STATUS_EX;
  1289. rgvar[i].vt = VT_UI4;
  1290. rgvar[i].ulVal = MsTagInfo->dwExtendedStatus;
  1291. i++;
  1292. }
  1293. // Deal with Extended status string
  1294. if (MsTagInfo->lptstrExtendedStatus) {
  1295. rgpspec[i].ulKind = PRSPEC_PROPID;
  1296. rgpspec[i].propid = PID_FAX_STATUS_STR_EX;
  1297. rgvar[i].vt = VT_LPWSTR;
  1298. rgvar[i].pwszVal = MsTagInfo->lptstrExtendedStatus;
  1299. i++;
  1300. }
  1301. // Deal with StartTime
  1302. if (MsTagInfo->StartTime != 0)
  1303. {
  1304. rgpspec[i].ulKind = PRSPEC_PROPID;
  1305. rgpspec[i].propid = PID_FAX_START_TIME;
  1306. rgvar[i].vt = VT_FILETIME;
  1307. rgvar[i].filetime = *(FILETIME*)&MsTagInfo->StartTime;
  1308. i++;
  1309. }
  1310. // Deal with EndTime
  1311. if (MsTagInfo->EndTime != 0)
  1312. {
  1313. rgpspec[i].ulKind = PRSPEC_PROPID;
  1314. rgpspec[i].propid = PID_FAX_END_TIME;
  1315. rgvar[i].vt = VT_FILETIME;
  1316. rgvar[i].filetime = *(FILETIME*)&MsTagInfo->EndTime;
  1317. i++;
  1318. }
  1319. hr = pPropertyStorage->WriteMultiple( i, //The number of properties being set
  1320. rgpspec, //Property specifiers
  1321. rgvar, //Array of PROPVARIANT values
  1322. 0 //Minimum value for property identifiers when they must be allocated
  1323. );
  1324. if (FAILED(hr))
  1325. {
  1326. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::WriteMultiple Failed, err : 0x%08X"), hr);
  1327. ec = ERROR_WRITE_FAULT;
  1328. goto exit;
  1329. }
  1330. RetVal = TRUE;
  1331. Assert (ec == ERROR_SUCCESS);
  1332. exit:
  1333. if (NULL != pPropertyStorage)
  1334. {
  1335. pPropertyStorage->Release();
  1336. }
  1337. if (NULL != pPropertySetStorage)
  1338. {
  1339. pPropertySetStorage->Release();
  1340. }
  1341. if (!RetVal)
  1342. {
  1343. SetLastError (ec);
  1344. }
  1345. return RetVal;
  1346. }
  1347. //*********************************************************************************
  1348. //* Name: GetMessageNTFSStorageProperties()
  1349. //* Author: Oded Sacher
  1350. //* Date: Nov 8, 1999
  1351. //*********************************************************************************
  1352. //* DESCRIPTION:
  1353. //* Fills FAX_MESSAGE structure.
  1354. //* The caller must free all strings.
  1355. //*
  1356. //* PARAMETERS:
  1357. //* [IN ] LPCTSTR lpctstrFileName
  1358. //* pointer to the file name.
  1359. //*
  1360. //* [OUT] PFAX_MESSAGE pMessage
  1361. //* The FAX_MESSAGE structure to be filled.
  1362. //*
  1363. //*
  1364. //* RETURN VALUE:
  1365. //* TRUE
  1366. //* If no error occured.
  1367. //* FALSE
  1368. //* If an error occured.
  1369. //*********************************************************************************
  1370. BOOL GetMessageNTFSStorageProperties(
  1371. LPCTSTR lpctstrFileName,
  1372. PFAX_MESSAGE pMessage
  1373. )
  1374. {
  1375. HRESULT hr;
  1376. IPropertySetStorage* pPropertySetStorage = NULL;
  1377. IPropertyStorage* pPropertyStorage = NULL;
  1378. PROPVARIANT rgvar[FAX_MESSAGE_PROPERTIES];
  1379. DEBUG_FUNCTION_NAME(TEXT("GetMessageNTFSStorageProperties"));
  1380. BOOL RetVal = FALSE;
  1381. DWORD i;
  1382. FAX_MESSAGE FaxMessage = {0};
  1383. HANDLE hFind;
  1384. WIN32_FIND_DATA FindFileData;
  1385. FILETIME FaxTime;
  1386. BOOL fFreePropVariant = FALSE;
  1387. DWORD ec = ERROR_SUCCESS;
  1388. Assert (pMessage && lpctstrFileName);
  1389. hFind = FindFirstFile( lpctstrFileName, &FindFileData);
  1390. if (INVALID_HANDLE_VALUE == hFind)
  1391. {
  1392. DebugPrintEx(
  1393. DEBUG_ERR,
  1394. TEXT("FindFirstFile failed (ec: %ld), File %s"),
  1395. GetLastError(),
  1396. lpctstrFileName);
  1397. }
  1398. else
  1399. {
  1400. Assert (0 == FindFileData.nFileSizeHigh);
  1401. FaxMessage.dwSize = FindFileData.nFileSizeLow;
  1402. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_SIZE;
  1403. if (!FindClose(hFind))
  1404. {
  1405. DebugPrintEx(
  1406. DEBUG_ERR,
  1407. TEXT("FindClose failed (ec: %ld)"),
  1408. GetLastError());
  1409. }
  1410. }
  1411. hr = StgOpenStorageEx( lpctstrFileName, //Points to path of compound file to create
  1412. STGM_READ | STGM_SHARE_DENY_WRITE | STGM_DIRECT, //Specifies the access mode for opening the storage object
  1413. STGFMT_FILE, //Specifies the storage file format
  1414. 0, //Reserved; must be zero
  1415. NULL, //Points to STGOPTIONS structure which specifies features of the storage object
  1416. 0, //Reserved; must be zero
  1417. IID_IPropertySetStorage ,//Specifies the GUID of the interface pointer
  1418. (void**)&pPropertySetStorage //Address of an interface pointer
  1419. );
  1420. if (FAILED(hr))
  1421. {
  1422. DebugPrintEx( DEBUG_ERR,TEXT("StgOpenStorageEx Failed, err : 0x%08X"), hr);
  1423. ec = ERROR_OPEN_FAILED;
  1424. goto exit;
  1425. }
  1426. hr = pPropertySetStorage->Open( FMTID_FaxProperties, //Format identifier of the property set to be created
  1427. STGM_READ | STGM_SHARE_EXCLUSIVE, //Storage mode of new property set
  1428. &pPropertyStorage //Address of output variable that receivesthe IPropertyStorage interface pointer
  1429. );
  1430. if (FAILED(hr))
  1431. {
  1432. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::Create Failed, err : 0x%08X"), hr);
  1433. ec = ERROR_OPEN_FAILED;
  1434. goto exit;
  1435. }
  1436. hr = pPropertyStorage->ReadMultiple( FAX_MESSAGE_PROPERTIES, //Count of properties being read
  1437. pspecFaxMessage, //Array of the properties to be read
  1438. rgvar //Array of PROPVARIANTs containing the property values on return
  1439. );
  1440. if (FAILED(hr))
  1441. {
  1442. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::ReadMultiple Failed, err : 0x%08X"), hr);
  1443. ec = ERROR_READ_FAULT;
  1444. goto exit;
  1445. }
  1446. fFreePropVariant = TRUE;
  1447. for (i = 0; i < FAX_MESSAGE_PROPERTIES; i++)
  1448. {
  1449. if (rgvar[i].vt != VT_EMPTY)
  1450. {
  1451. switch (pspecFaxMessage[i].propid)
  1452. {
  1453. case PID_FAX_CSID:
  1454. FaxMessage.lpctstrCsid = StringDup (rgvar[i].pwszVal);
  1455. if (FaxMessage.lpctstrCsid == NULL)
  1456. {
  1457. ec = GetLastError ();
  1458. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1459. goto exit;
  1460. }
  1461. break;
  1462. case PID_FAX_TSID:
  1463. FaxMessage.lpctstrTsid = StringDup (rgvar[i].pwszVal);
  1464. if (FaxMessage.lpctstrTsid == NULL)
  1465. {
  1466. ec = GetLastError ();
  1467. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1468. goto exit;
  1469. }
  1470. break;
  1471. case PID_FAX_PORT:
  1472. FaxMessage.lpctstrDeviceName = StringDup (rgvar[i].pwszVal);
  1473. if (FaxMessage.lpctstrDeviceName == NULL)
  1474. {
  1475. ec = GetLastError ();
  1476. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1477. goto exit;
  1478. }
  1479. break;
  1480. case PID_FAX_ROUTING:
  1481. FaxMessage.lpctstrRoutingInfo = StringDup (rgvar[i].pwszVal);
  1482. if (FaxMessage.lpctstrRoutingInfo == NULL)
  1483. {
  1484. ec = GetLastError ();
  1485. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1486. goto exit;
  1487. }
  1488. break;
  1489. case PID_FAX_CALLERID:
  1490. FaxMessage.lpctstrCallerID = StringDup (rgvar[i].pwszVal);
  1491. if (FaxMessage.lpctstrCallerID == NULL)
  1492. {
  1493. ec = GetLastError ();
  1494. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1495. goto exit;
  1496. }
  1497. break;
  1498. case PID_FAX_DOCUMENT:
  1499. FaxMessage.lpctstrDocumentName = StringDup (rgvar[i].pwszVal);
  1500. if (FaxMessage.lpctstrDocumentName == NULL)
  1501. {
  1502. ec = GetLastError ();
  1503. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1504. goto exit;
  1505. }
  1506. break;
  1507. case PID_FAX_SUBJECT:
  1508. FaxMessage.lpctstrSubject = StringDup (rgvar[i].pwszVal);
  1509. if (FaxMessage.lpctstrSubject == NULL)
  1510. {
  1511. ec = GetLastError ();
  1512. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1513. goto exit;
  1514. }
  1515. break;
  1516. case PID_FAX_RETRIES:
  1517. FaxMessage.dwRetries = rgvar[i].ulVal;
  1518. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_RETRIES;
  1519. break;
  1520. case PID_FAX_PAGES:
  1521. FaxMessage.dwPageCount = rgvar[i].ulVal;
  1522. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_PAGE_COUNT;
  1523. break;
  1524. case PID_FAX_TYPE:
  1525. FaxMessage.dwJobType = rgvar[i].ulVal;
  1526. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TYPE;
  1527. break;
  1528. case PID_FAX_PRIORITY:
  1529. FaxMessage.Priority = (FAX_ENUM_PRIORITY_TYPE)rgvar[i].ulVal;
  1530. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_PRIORITY;
  1531. break;
  1532. case PID_FAX_START_TIME:
  1533. FaxTime = rgvar[i].filetime;
  1534. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmTransmissionStartTime))
  1535. {
  1536. ec = GetLastError ();
  1537. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1538. goto exit;
  1539. }
  1540. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TRANSMISSION_START_TIME;
  1541. break;
  1542. case PID_FAX_END_TIME:
  1543. FaxTime = rgvar[i].filetime;
  1544. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmTransmissionEndTime))
  1545. {
  1546. ec = GetLastError ();
  1547. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1548. goto exit;
  1549. }
  1550. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_TRANSMISSION_END_TIME;
  1551. break;
  1552. case PID_FAX_SUBMISSION_TIME:
  1553. FaxTime = rgvar[i].filetime;
  1554. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmSubmissionTime))
  1555. {
  1556. ec = GetLastError ();
  1557. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1558. goto exit;
  1559. }
  1560. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_SUBMISSION_TIME;
  1561. break;
  1562. case PID_FAX_ORIGINAL_SCHED_TIME:
  1563. FaxTime = rgvar[i].filetime;
  1564. if (!FileTimeToSystemTime(&FaxTime, &FaxMessage.tmOriginalScheduleTime))
  1565. {
  1566. ec = GetLastError ();
  1567. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1568. goto exit;
  1569. }
  1570. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_ORIGINAL_SCHEDULE_TIME;
  1571. break;
  1572. case PID_FAX_SENDER_USER_NAME:
  1573. FaxMessage.lpctstrSenderUserName = StringDup (rgvar[i].pwszVal);
  1574. if (FaxMessage.lpctstrSenderUserName == NULL)
  1575. {
  1576. ec = GetLastError ();
  1577. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1578. goto exit;
  1579. }
  1580. break;
  1581. case PID_FAX_RECIP_NAME:
  1582. FaxMessage.lpctstrRecipientName = StringDup (rgvar[i].pwszVal);
  1583. if (FaxMessage.lpctstrRecipientName == NULL)
  1584. {
  1585. ec = GetLastError ();
  1586. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1587. goto exit;
  1588. }
  1589. break;
  1590. case PID_FAX_RECIP_NUMBER:
  1591. FaxMessage.lpctstrRecipientNumber = StringDup (rgvar[i].pwszVal);
  1592. if (FaxMessage.lpctstrRecipientNumber == NULL)
  1593. {
  1594. ec = GetLastError ();
  1595. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1596. goto exit;
  1597. }
  1598. break;
  1599. case PID_FAX_SENDER_NAME:
  1600. FaxMessage.lpctstrSenderName = StringDup (rgvar[i].pwszVal);
  1601. if (FaxMessage.lpctstrSenderName == NULL)
  1602. {
  1603. ec = GetLastError ();
  1604. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1605. goto exit;
  1606. }
  1607. break;
  1608. case PID_FAX_SENDER_NUMBER:
  1609. FaxMessage.lpctstrSenderNumber = StringDup (rgvar[i].pwszVal);
  1610. if (FaxMessage.lpctstrSenderNumber == NULL)
  1611. {
  1612. ec = GetLastError ();
  1613. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1614. goto exit;
  1615. }
  1616. break;
  1617. case PID_FAX_SENDER_BILLING:
  1618. FaxMessage.lpctstrBillingCode = StringDup (rgvar[i].pwszVal);
  1619. if (FaxMessage.lpctstrBillingCode == NULL)
  1620. {
  1621. ec = GetLastError ();
  1622. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1623. goto exit;
  1624. }
  1625. break;
  1626. case PID_FAX_STATUS:
  1627. FaxMessage.dwQueueStatus = rgvar[i].ulVal;
  1628. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_QUEUE_STATUS;
  1629. break;
  1630. case PID_FAX_STATUS_EX:
  1631. FaxMessage.dwExtendedStatus = rgvar[i].ulVal;
  1632. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_STATUS_EX;
  1633. break;
  1634. case PID_FAX_STATUS_STR_EX:
  1635. FaxMessage.lpctstrExtendedStatus = StringDup (rgvar[i].pwszVal);
  1636. if (FaxMessage.lpctstrExtendedStatus == NULL)
  1637. {
  1638. ec = GetLastError ();
  1639. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, err : %ld"), ec);
  1640. goto exit;
  1641. }
  1642. break;
  1643. case PID_FAX_BROADCAST_ID:
  1644. FaxMessage.dwlBroadcastId = *(DWORDLONG*)&rgvar[i].uhVal;
  1645. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_BROADCAST_ID;
  1646. break;
  1647. default:
  1648. Assert (pspecFaxMessage[i].propid == PID_FAX_SENDER_BILLING); //Assert (FALSE);
  1649. }
  1650. }
  1651. }
  1652. // Get Unique JobId out of FileName
  1653. if (!GetUniqueJobIdFromFileName( lpctstrFileName, &FaxMessage.dwlMessageId))
  1654. {
  1655. ec = GetLastError();
  1656. DebugPrintEx( DEBUG_ERR, TEXT("GetUniqueJobIdFromFileName Failed, err : %ld"), ec);
  1657. goto exit;
  1658. }
  1659. FaxMessage.dwValidityMask |= FAX_JOB_FIELD_MESSAGE_ID;
  1660. FaxMessage.dwSizeOfStruct = sizeof(FAX_MESSAGE);
  1661. CopyMemory (pMessage, &FaxMessage, sizeof(FAX_MESSAGE));
  1662. RetVal = TRUE;
  1663. Assert (ec == ERROR_SUCCESS);
  1664. exit:
  1665. if (NULL != pPropertyStorage)
  1666. {
  1667. pPropertyStorage->Release();
  1668. }
  1669. if (NULL != pPropertySetStorage)
  1670. {
  1671. pPropertySetStorage->Release();
  1672. }
  1673. if (fFreePropVariant == TRUE)
  1674. {
  1675. hr = FreePropVariantArray( FAX_MESSAGE_PROPERTIES, //Count of elements in the structure
  1676. rgvar //Pointer to the PROPVARIANT structure
  1677. );
  1678. if (FAILED(hr))
  1679. {
  1680. DebugPrintEx( DEBUG_ERR,TEXT("FreePropVariantArray Failed, err : 0x%08X"), hr);
  1681. }
  1682. }
  1683. if (RetVal == FALSE)
  1684. {
  1685. FreeMessageBuffer (&FaxMessage, FALSE);
  1686. SetLastError (ec);
  1687. }
  1688. return RetVal;
  1689. }
  1690. BOOL
  1691. GetUniqueJobIdFromFileName (
  1692. LPCWSTR lpctstrFileName,
  1693. DWORDLONG* pdwlUniqueJobId)
  1694. {
  1695. WCHAR lpwstrTmp[MAX_PATH];
  1696. DWORDLONG dwlJobId = 0;
  1697. LPWSTR lpwstrJobId = NULL;
  1698. _wsplitpath (lpctstrFileName, NULL, NULL, lpwstrTmp, NULL);
  1699. lpwstrJobId = wcschr( lpwstrTmp, L'$');
  1700. if (lpwstrJobId == NULL)
  1701. {
  1702. if (!swscanf(lpwstrTmp, TEXT("%I64x"), &dwlJobId))
  1703. {
  1704. return FALSE;
  1705. }
  1706. }
  1707. else
  1708. {
  1709. if (!swscanf((lpwstrJobId+1), TEXT("%I64x"), &dwlJobId))
  1710. {
  1711. return FALSE;
  1712. }
  1713. }
  1714. *pdwlUniqueJobId = dwlJobId;
  1715. return TRUE;
  1716. }
  1717. //*********************************************************************************
  1718. //* Name: GetPersonalProfNTFSStorageProperties()
  1719. //* Author: Oded Sacher
  1720. //* Date: Nov 8, 1999
  1721. //*********************************************************************************
  1722. //* DESCRIPTION:
  1723. //* Fills PFAX_PERSONAL_PROFILE structure with sender or recipient information.
  1724. //* The caller must free all strings.
  1725. //*
  1726. //* PARAMETERS:
  1727. //* [IN ] LPCTSTR lpctstrFileName
  1728. //* pointer to the file name.
  1729. //* [IN ] FAX_ENUM_PERSONAL_PROF_TYPES PersonalProfType
  1730. //* Can be RECIPIENT_PERSONAL_PROF or SENDER_PERSONAL_PROF
  1731. //*
  1732. //* [OUT] PFAX_PERSONAL_PROFILE pPersonalProfile
  1733. //* The PFAX_PERSONAL_PROFILE structure to be filled.
  1734. //*
  1735. //*
  1736. //* RETURN VALUE:
  1737. //* TRUE
  1738. //* If no error occured.
  1739. //* FALSE
  1740. //* If an error occured.
  1741. //*********************************************************************************
  1742. BOOL GetPersonalProfNTFSStorageProperties(
  1743. LPCTSTR lpctstrFileName,
  1744. FAX_ENUM_PERSONAL_PROF_TYPES PersonalProfType,
  1745. PFAX_PERSONAL_PROFILE pPersonalProfile
  1746. )
  1747. {
  1748. HRESULT hr;
  1749. IPropertySetStorage* pPropertySetStorage = NULL;
  1750. IPropertyStorage* pPropertyStorage = NULL;
  1751. const PROPSPEC* pspec;
  1752. DWORD dwPropertiesCnt;
  1753. DEBUG_FUNCTION_NAME(TEXT("GetPersonalProfNTFSStorageProperties"));
  1754. BOOL RetVal = FALSE;
  1755. DWORD i;
  1756. FAX_PERSONAL_PROFILE FaxPersonalProfile = {0};
  1757. BOOL fFreePropVariant = FALSE;
  1758. PROPVARIANT* rgvar;
  1759. DWORD ec = ERROR_SUCCESS;
  1760. Assert (PersonalProfType == RECIPIENT_PERSONAL_PROF ||
  1761. PersonalProfType == SENDER_PERSONAL_PROF);
  1762. if (PersonalProfType == RECIPIENT_PERSONAL_PROF)
  1763. {
  1764. pspec = pspecFaxRecipient;
  1765. dwPropertiesCnt = FAX_RECIP_PROPERTIES;
  1766. }
  1767. else
  1768. {
  1769. pspec = pspecFaxSender;
  1770. dwPropertiesCnt = FAX_SENDER_PROPERTIES;
  1771. }
  1772. rgvar = (PROPVARIANT*) MemAlloc( dwPropertiesCnt * sizeof(PROPVARIANT) );
  1773. if (!rgvar) {
  1774. DebugPrintEx( DEBUG_ERR,TEXT("Failed to allocate array of PROPVARIANT values"));
  1775. ec = ERROR_OUTOFMEMORY;
  1776. goto exit;
  1777. }
  1778. hr = StgOpenStorageEx( lpctstrFileName, //Points to path of compound file to create
  1779. STGM_READ | STGM_SHARE_DENY_WRITE | STGM_DIRECT, //Specifies the access mode for opening the storage object
  1780. STGFMT_FILE, //Specifies the storage file format
  1781. 0, //Reserved; must be zero
  1782. NULL, //Points to STGOPTIONS structure which specifies features of the storage object
  1783. 0, //Reserved; must be zero
  1784. IID_IPropertySetStorage ,//Specifies the GUID of the interface pointer
  1785. (void**)&pPropertySetStorage //Address of an interface pointer
  1786. );
  1787. if (FAILED(hr))
  1788. {
  1789. DebugPrintEx( DEBUG_ERR,TEXT("StgOpenStorageEx Failed, err :"), hr);
  1790. ec = ERROR_OPEN_FAILED;
  1791. goto exit;
  1792. }
  1793. hr = pPropertySetStorage->Open( FMTID_FaxProperties, //Format identifier of the property set to be created
  1794. STGM_READ|STGM_SHARE_EXCLUSIVE, //Storage mode of new property set
  1795. &pPropertyStorage //Address of output variable that receivesthe IPropertyStorage interface pointer
  1796. );
  1797. if (FAILED(hr))
  1798. {
  1799. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::Create Failed, err :"), hr);
  1800. ec = ERROR_OPEN_FAILED;
  1801. goto exit;
  1802. }
  1803. hr = pPropertyStorage->ReadMultiple( dwPropertiesCnt, //Count of properties being read
  1804. pspec, //Array of the properties to be read
  1805. rgvar //Array of PROPVARIANTs containing the property values on return
  1806. );
  1807. if (FAILED(hr))
  1808. {
  1809. DebugPrintEx( DEBUG_ERR,TEXT("IPropertySetStorage::ReadMultiple Failed, err :"), hr);
  1810. ec = ERROR_READ_FAULT;
  1811. goto exit;
  1812. }
  1813. fFreePropVariant = TRUE;
  1814. for (i = 0; i < dwPropertiesCnt; i++)
  1815. {
  1816. if (rgvar[i].vt != VT_EMPTY)
  1817. {
  1818. switch (pspec[i].propid)
  1819. {
  1820. case PID_FAX_RECIP_NAME:
  1821. case PID_FAX_SENDER_NAME:
  1822. FaxPersonalProfile.lptstrName = StringDup (rgvar[i].pwszVal);
  1823. if (FaxPersonalProfile.lptstrName == NULL)
  1824. {
  1825. ec = GetLastError ();
  1826. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1827. goto exit;
  1828. }
  1829. break;
  1830. case PID_FAX_RECIP_NUMBER:
  1831. case PID_FAX_SENDER_NUMBER:
  1832. FaxPersonalProfile.lptstrFaxNumber = StringDup (rgvar[i].pwszVal);
  1833. if (FaxPersonalProfile.lptstrFaxNumber == NULL)
  1834. {
  1835. ec = GetLastError ();
  1836. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1837. goto exit;
  1838. }
  1839. break;
  1840. case PID_FAX_RECIP_COMPANY:
  1841. case PID_FAX_SENDER_COMPANY:
  1842. FaxPersonalProfile.lptstrCompany = StringDup (rgvar[i].pwszVal);
  1843. if (FaxPersonalProfile.lptstrCompany == NULL)
  1844. {
  1845. ec = GetLastError ();
  1846. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1847. goto exit;
  1848. }
  1849. break;
  1850. case PID_FAX_RECIP_STREET:
  1851. case PID_FAX_SENDER_STREET:
  1852. FaxPersonalProfile.lptstrStreetAddress = StringDup (rgvar[i].pwszVal);
  1853. if (FaxPersonalProfile.lptstrStreetAddress == NULL)
  1854. {
  1855. ec = GetLastError ();
  1856. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1857. goto exit;
  1858. }
  1859. break;
  1860. case PID_FAX_RECIP_CITY:
  1861. case PID_FAX_SENDER_CITY:
  1862. FaxPersonalProfile.lptstrCity = StringDup (rgvar[i].pwszVal);
  1863. if (FaxPersonalProfile.lptstrCity == NULL)
  1864. {
  1865. ec = GetLastError ();
  1866. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1867. goto exit;
  1868. }
  1869. break;
  1870. case PID_FAX_RECIP_STATE:
  1871. case PID_FAX_SENDER_STATE:
  1872. FaxPersonalProfile.lptstrState = StringDup (rgvar[i].pwszVal);
  1873. if (FaxPersonalProfile.lptstrState == NULL)
  1874. {
  1875. ec = GetLastError ();
  1876. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1877. goto exit;
  1878. }
  1879. break;
  1880. case PID_FAX_RECIP_ZIP:
  1881. case PID_FAX_SENDER_ZIP:
  1882. FaxPersonalProfile.lptstrZip = StringDup (rgvar[i].pwszVal);
  1883. if (FaxPersonalProfile.lptstrZip == NULL)
  1884. {
  1885. ec = GetLastError ();
  1886. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1887. goto exit;
  1888. }
  1889. break;
  1890. case PID_FAX_RECIP_COUNTRY:
  1891. case PID_FAX_SENDER_COUNTRY:
  1892. FaxPersonalProfile.lptstrCountry = StringDup (rgvar[i].pwszVal);
  1893. if (FaxPersonalProfile.lptstrCountry == NULL)
  1894. {
  1895. ec = GetLastError ();
  1896. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1897. goto exit;
  1898. }
  1899. break;
  1900. case PID_FAX_RECIP_TITLE:
  1901. case PID_FAX_SENDER_TITLE:
  1902. FaxPersonalProfile.lptstrTitle = StringDup (rgvar[i].pwszVal);
  1903. if (FaxPersonalProfile.lptstrTitle == NULL)
  1904. {
  1905. ec = GetLastError ();
  1906. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1907. goto exit;
  1908. }
  1909. break;
  1910. case PID_FAX_RECIP_DEPARTMENT:
  1911. case PID_FAX_SENDER_DEPARTMENT:
  1912. FaxPersonalProfile.lptstrDepartment = StringDup (rgvar[i].pwszVal);
  1913. if (FaxPersonalProfile.lptstrDepartment == NULL)
  1914. {
  1915. ec = GetLastError ();
  1916. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1917. goto exit;
  1918. }
  1919. break;
  1920. case PID_FAX_RECIP_OFFICE_LOCATION:
  1921. case PID_FAX_SENDER_OFFICE_LOCATION:
  1922. FaxPersonalProfile.lptstrOfficeLocation = StringDup (rgvar[i].pwszVal);
  1923. if (FaxPersonalProfile.lptstrOfficeLocation == NULL)
  1924. {
  1925. ec = GetLastError ();
  1926. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1927. goto exit;
  1928. }
  1929. break;
  1930. case PID_FAX_RECIP_HOME_PHONE:
  1931. case PID_FAX_SENDER_HOME_PHONE:
  1932. FaxPersonalProfile.lptstrHomePhone = StringDup (rgvar[i].pwszVal);
  1933. if (FaxPersonalProfile.lptstrHomePhone == NULL)
  1934. {
  1935. ec = GetLastError ();
  1936. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1937. goto exit;
  1938. }
  1939. break;
  1940. case PID_FAX_RECIP_OFFICE_PHONE:
  1941. case PID_FAX_SENDER_OFFICE_PHONE:
  1942. FaxPersonalProfile.lptstrOfficePhone = StringDup (rgvar[i].pwszVal);
  1943. if (FaxPersonalProfile.lptstrOfficePhone == NULL)
  1944. {
  1945. ec = GetLastError ();
  1946. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1947. goto exit;
  1948. }
  1949. break;
  1950. case PID_FAX_RECIP_EMAIL:
  1951. case PID_FAX_SENDER_EMAIL:
  1952. FaxPersonalProfile.lptstrEmail = StringDup (rgvar[i].pwszVal);
  1953. if (FaxPersonalProfile.lptstrEmail == NULL)
  1954. {
  1955. ec = GetLastError ();
  1956. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1957. goto exit;
  1958. }
  1959. break;
  1960. case PID_FAX_SENDER_BILLING:
  1961. FaxPersonalProfile.lptstrBillingCode = StringDup (rgvar[i].pwszVal);
  1962. if (FaxPersonalProfile.lptstrBillingCode == NULL)
  1963. {
  1964. ec = GetLastError ();
  1965. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1966. goto exit;
  1967. }
  1968. break;
  1969. case PID_FAX_SENDER_TSID:
  1970. FaxPersonalProfile.lptstrTSID = StringDup (rgvar[i].pwszVal);
  1971. if (FaxPersonalProfile.lptstrTSID == NULL)
  1972. {
  1973. ec = GetLastError ();
  1974. DebugPrintEx( DEBUG_ERR,TEXT("StringDup Failed, error %ld"), ec);
  1975. goto exit;
  1976. }
  1977. break;
  1978. default:
  1979. Assert (pspecFaxMessage[i].propid == PID_FAX_SENDER_TSID); //Assert (FALSE);
  1980. }
  1981. }
  1982. }
  1983. FaxPersonalProfile.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  1984. CopyMemory (pPersonalProfile, &FaxPersonalProfile, sizeof(FAX_PERSONAL_PROFILE));
  1985. RetVal = TRUE;
  1986. Assert (ec == ERROR_SUCCESS);
  1987. exit:
  1988. if (NULL != pPropertyStorage)
  1989. {
  1990. pPropertyStorage->Release();
  1991. }
  1992. if (NULL != pPropertySetStorage)
  1993. {
  1994. pPropertySetStorage->Release();
  1995. }
  1996. if (fFreePropVariant == TRUE)
  1997. {
  1998. hr = FreePropVariantArray( dwPropertiesCnt, //Count of elements in the structure
  1999. rgvar //Pointer to the PROPVARIANT structure
  2000. );
  2001. if (FAILED(hr))
  2002. {
  2003. DebugPrintEx( DEBUG_ERR,TEXT("FreePropVariantArray Failed, err :"), hr);
  2004. }
  2005. }
  2006. MemFree(rgvar);
  2007. if (RetVal == FALSE)
  2008. {
  2009. FreePersonalProfile (&FaxPersonalProfile, FALSE);
  2010. SetLastError (ec);
  2011. }
  2012. return RetVal;
  2013. }
  2014. /******************************************************************************
  2015. * Name: GetRecievedMessageFileName
  2016. * Author: Oded Sacher
  2017. *******************************************************************************
  2018. DESCRIPTION:
  2019. Returns the file name of the specified message from the Inbox archive.
  2020. PARAMETERS:
  2021. [IN] DWORDLONG dwlUniqueId [IN/OUT]
  2022. The message unique ID.
  2023. RETURN VALUE:
  2024. Pointer to the file name on success. Null if failed
  2025. REMARKS:
  2026. Returns a pointer to the file name specified by unique message ID.
  2027. If the function fails the function returns NULL.
  2028. The caller must call MemFree to deallocate the returned string
  2029. *******************************************************************************/
  2030. LPWSTR
  2031. GetRecievedMessageFileName(
  2032. IN DWORDLONG dwlUniqueId
  2033. )
  2034. {
  2035. WCHAR wszFileName[MAX_PATH];
  2036. WCHAR wszFullPathFileName[MAX_PATH];
  2037. DWORD dwCount;
  2038. DEBUG_FUNCTION_NAME(TEXT("GetRecievedMessageFileName"));
  2039. DWORD ec = ERROR_SUCCESS;
  2040. WCHAR wszArchiveFolder [MAX_PATH];
  2041. LPWSTR lpwstrFilePart;
  2042. EnterCriticalSection (&g_CsConfig);
  2043. lstrcpyn (wszArchiveFolder, g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder, MAX_PATH);
  2044. LeaveCriticalSection (&g_CsConfig);
  2045. swprintf (wszFileName, L"%I64x", dwlUniqueId);
  2046. dwCount = SearchPath (wszArchiveFolder, // search path
  2047. wszFileName, // file name
  2048. FAX_TIF_FILE_DOT_EXT, // file extension
  2049. MAX_PATH, // size of buffer
  2050. wszFullPathFileName, // found file name buffer
  2051. &lpwstrFilePart // file component
  2052. );
  2053. if (0 == dwCount)
  2054. {
  2055. DebugPrintEx(
  2056. DEBUG_ERR,
  2057. TEXT("SearchPath Failed, Error %ld"), GetLastError());
  2058. return NULL;
  2059. }
  2060. if (dwCount > MAX_PATH)
  2061. {
  2062. DebugPrintEx(
  2063. DEBUG_ERR,
  2064. TEXT("SearchPath Failed, File name bigger than MAX_PATH"));
  2065. SetLastError (E_FAIL);
  2066. return NULL;
  2067. }
  2068. return StringDup (wszFullPathFileName);
  2069. }
  2070. /******************************************************************************
  2071. * Name: GetSentMessageFileName
  2072. * Author: Oded Sacher
  2073. *******************************************************************************
  2074. DESCRIPTION:
  2075. Returns the file name of the specified message from the Sent items archive.
  2076. PARAMETERS:
  2077. [IN] DWORDLONG dwlUniqueId
  2078. The message unique ID.
  2079. [IN] PSID pSid
  2080. Pointer to the sending user SID.
  2081. If this value is NULL - the caller has access to everyone's sent items archive
  2082. and can get the file name of all the messages in that archive.
  2083. RETURN VALUE:
  2084. Pointer to the file name on success. Null if failed.
  2085. REMARKS:
  2086. Returns a pointer to the file name specified by unique message ID and sending user SID.
  2087. If the function fails the function returns NULL.
  2088. The caller must call MemFree to deallocate the returned string
  2089. *******************************************************************************/
  2090. LPWSTR
  2091. GetSentMessageFileName(
  2092. IN DWORDLONG dwlUniqueId,
  2093. IN PSID pSid
  2094. )
  2095. {
  2096. WCHAR wszFileName[MAX_PATH] = {0};
  2097. WCHAR wszFullPathFileName[MAX_PATH] = {0};
  2098. int Count;
  2099. DWORD dwCount;
  2100. DEBUG_FUNCTION_NAME(TEXT("GetSentMessageFileName"));
  2101. WCHAR wszArchiveFolder [MAX_PATH];
  2102. EnterCriticalSection (&g_CsConfig);
  2103. lstrcpyn (wszArchiveFolder, g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder, MAX_PATH);
  2104. LeaveCriticalSection (&g_CsConfig);
  2105. if (pSid != NULL)
  2106. {
  2107. LPWSTR lpwstrFilePart;
  2108. LPWSTR lpwstrUserSid;
  2109. if (!ConvertSidToStringSid (pSid, &lpwstrUserSid))
  2110. {
  2111. DebugPrintEx(
  2112. DEBUG_ERR,
  2113. TEXT("ConvertSidToStringSid Failed, error : %ld"),
  2114. GetLastError());
  2115. return NULL;
  2116. }
  2117. Count = _snwprintf (wszFileName,
  2118. ARR_SIZE(wszFileName) -1,
  2119. L"%s$%I64x",
  2120. lpwstrUserSid,
  2121. dwlUniqueId);
  2122. if (Count < 0)
  2123. {
  2124. DebugPrintEx(
  2125. DEBUG_ERR,
  2126. TEXT("_snwprintf Failed, File name bigger than MAX_PATH"));
  2127. SetLastError (E_FAIL);
  2128. LocalFree (lpwstrUserSid);
  2129. return NULL;
  2130. }
  2131. LocalFree (lpwstrUserSid);
  2132. dwCount = SearchPath (wszArchiveFolder, // search path
  2133. wszFileName, // file name
  2134. FAX_TIF_FILE_DOT_EXT, // file extension
  2135. MAX_PATH, // size of buffer
  2136. wszFullPathFileName, // found file name buffer
  2137. &lpwstrFilePart // file component
  2138. );
  2139. if (0 == dwCount)
  2140. {
  2141. DebugPrintEx(
  2142. DEBUG_ERR,
  2143. TEXT("SearchPath Failed, Error %ld"), GetLastError());
  2144. return NULL;
  2145. }
  2146. if (dwCount > MAX_PATH)
  2147. {
  2148. DebugPrintEx(
  2149. DEBUG_ERR,
  2150. TEXT("SearchPath Failed, File name bigger than MAX_PATH"));
  2151. SetLastError (E_FAIL);
  2152. return NULL;
  2153. }
  2154. return StringDup (wszFullPathFileName);
  2155. }
  2156. else
  2157. {
  2158. HANDLE hSearch = INVALID_HANDLE_VALUE;
  2159. WIN32_FIND_DATA FindFileData;
  2160. DWORD ec = ERROR_SUCCESS;
  2161. Count = _snwprintf (wszFullPathFileName,
  2162. MAX_PATH -1,
  2163. L"%s\\*$%I64x.%s",
  2164. wszArchiveFolder,
  2165. dwlUniqueId,
  2166. FAX_TIF_FILE_EXT);
  2167. if (Count < 0)
  2168. {
  2169. DebugPrintEx(
  2170. DEBUG_ERR,
  2171. TEXT("_snwprintf Failed, File name bigger than MAX_PATH"));
  2172. SetLastError (E_FAIL);
  2173. return NULL;
  2174. }
  2175. hSearch = FindFirstFile (wszFullPathFileName, // file name
  2176. &FindFileData // data buffer
  2177. );
  2178. if (INVALID_HANDLE_VALUE == hSearch)
  2179. {
  2180. DebugPrintEx(
  2181. DEBUG_ERR,
  2182. TEXT("FindFirstFile Failed, error : %ld"),
  2183. GetLastError());
  2184. return NULL;
  2185. }
  2186. Count = _snwprintf (wszFullPathFileName,
  2187. MAX_PATH -1,
  2188. L"%s\\%s",
  2189. wszArchiveFolder,
  2190. FindFileData.cFileName);
  2191. if (Count < 0)
  2192. {
  2193. ec = E_FAIL;
  2194. DebugPrintEx(
  2195. DEBUG_ERR,
  2196. TEXT("_snwprintf Failed, File name bigger than MAX_PATH"));
  2197. }
  2198. if (!FindClose (hSearch))
  2199. {
  2200. ec = GetLastError();
  2201. DebugPrintEx(
  2202. DEBUG_ERR,
  2203. TEXT("FindClose Failed, error : %ld"),
  2204. ec);
  2205. }
  2206. if (ERROR_SUCCESS != ec)
  2207. {
  2208. SetLastError(ec);
  2209. return NULL;
  2210. }
  2211. return StringDup (wszFullPathFileName);
  2212. }
  2213. }
  2214. DWORD
  2215. IsValidArchiveFolder (
  2216. LPWSTR lpwstrFolder,
  2217. FAX_ENUM_MESSAGE_FOLDER Folder
  2218. )
  2219. /*++
  2220. Routine name : IsValidArchiveFolder
  2221. Routine description:
  2222. Validates a folder is good for archiving. Make sure to lock g_CsConfig
  2223. Author:
  2224. Eran Yariv (EranY), Nov, 1999
  2225. Arguments:
  2226. lpwstrFolder [in] - Folder in quetion
  2227. Folder [in] - 'Inbox' or 'Sent items'
  2228. Return Value:
  2229. Win32 error code. ERROR_SUCCESS if the folder can be used for archiving.
  2230. Otherwise, the Win32 error code to return to the caller.
  2231. --*/
  2232. {
  2233. DWORD dwLen;
  2234. DWORD ec = ERROR_SUCCESS;
  2235. BOOL IsSameDir;
  2236. FAX_ENUM_MESSAGE_FOLDER OtherFolder;
  2237. DEBUG_FUNCTION_NAME(TEXT("IsValidArchiveFolder"));
  2238. Assert (FAX_MESSAGE_FOLDER_SENTITEMS == Folder ||
  2239. FAX_MESSAGE_FOLDER_INBOX == Folder);
  2240. if ((NULL == lpwstrFolder) || (L'\0' == lpwstrFolder[0]))
  2241. {
  2242. DebugPrintEx(
  2243. DEBUG_ERR,
  2244. TEXT("Empty archive folder specified"));
  2245. return ERROR_INVALID_PARAMETER;
  2246. }
  2247. if ((dwLen = lstrlenW (lpwstrFolder)) > MAX_ARCHIVE_FOLDER_PATH)
  2248. {
  2249. DebugPrintEx(
  2250. DEBUG_ERR,
  2251. TEXT("DB file name exceeds MAX_PATH"));
  2252. return ERROR_BUFFER_OVERFLOW;
  2253. }
  2254. if (L'\\' == lpwstrFolder[dwLen - 1])
  2255. {
  2256. //
  2257. // Archive name should not end with a backslash.
  2258. //
  2259. lpwstrFolder[dwLen - 1] = (WCHAR)'\0';
  2260. }
  2261. //
  2262. // Compare Sent items and Inbox directory
  2263. //
  2264. if (FAX_MESSAGE_FOLDER_SENTITEMS == Folder)
  2265. {
  2266. OtherFolder = FAX_MESSAGE_FOLDER_INBOX;
  2267. }
  2268. else
  2269. {
  2270. OtherFolder = FAX_MESSAGE_FOLDER_SENTITEMS;
  2271. }
  2272. ec = IsValidFaxFolder(lpwstrFolder);
  2273. if(ERROR_SUCCESS != ec)
  2274. {
  2275. //
  2276. // The folder does not exist or we don't
  2277. // have access rights
  2278. //
  2279. DebugPrintEx( DEBUG_ERR,
  2280. TEXT("IsValidFaxFolder failed for folder : %s (ec=%lu)."),
  2281. lpwstrFolder,
  2282. ec);
  2283. return ec;
  2284. }
  2285. //
  2286. // Check Queue folder conflict
  2287. //
  2288. ec = CheckToSeeIfSameDir(
  2289. lpwstrFolder,
  2290. g_wszFaxQueueDir,
  2291. &IsSameDir);
  2292. if (ERROR_SUCCESS != ec)
  2293. {
  2294. DebugPrintEx(
  2295. DEBUG_ERR,
  2296. TEXT("CheckToSeeIfSameDir with %ld"), ec);
  2297. return ec;
  2298. }
  2299. if (TRUE == IsSameDir)
  2300. {
  2301. DebugPrintEx(
  2302. DEBUG_ERR,
  2303. TEXT("Inbox / Sent items point to the queue directory directory. %s and %s"),
  2304. lpwstrFolder,
  2305. g_wszFaxQueueDir);
  2306. return FAX_ERR_DIRECTORY_IN_USE;
  2307. }
  2308. if (g_ArchivesConfig[OtherFolder].bUseArchive)
  2309. {
  2310. //
  2311. // Check the other folder path
  2312. //
  2313. Assert (g_ArchivesConfig[OtherFolder].lpcstrFolder);
  2314. ec = CheckToSeeIfSameDir( lpwstrFolder,
  2315. g_ArchivesConfig[OtherFolder].lpcstrFolder,
  2316. &IsSameDir);
  2317. if (ERROR_SUCCESS != ec)
  2318. {
  2319. DebugPrintEx(
  2320. DEBUG_ERR,
  2321. TEXT("CheckToSeeIfSameDir with %ld"), ec);
  2322. return ec;
  2323. }
  2324. if (TRUE == IsSameDir)
  2325. {
  2326. DebugPrintEx(
  2327. DEBUG_ERR,
  2328. TEXT("Inbox and Sent items point to the same directory. %s and %s"),
  2329. lpwstrFolder,
  2330. g_ArchivesConfig[OtherFolder].lpcstrFolder);
  2331. return FAX_ERR_DIRECTORY_IN_USE;
  2332. }
  2333. }
  2334. Assert (ERROR_SUCCESS == ec);
  2335. return ERROR_SUCCESS;
  2336. } // IsValidArchiveFolder
  2337. BOOL
  2338. GetMessageIdAndUserSid (
  2339. LPCWSTR lpcwstrFullPathFileName,
  2340. FAX_ENUM_MESSAGE_FOLDER Folder,
  2341. PSID* lppUserSid,
  2342. DWORDLONG* pdwlMessageId
  2343. /*++
  2344. Routine name : GetSentMessageUserSid
  2345. Routine description:
  2346. Returns the user sid associated with a sent message - optional.
  2347. Returns the message unique id - optional.
  2348. The caller must call LocalFree to deallocate the SID bufffer
  2349. Author:
  2350. Oded Sacher (OdedS), Jan, 2000
  2351. Arguments:
  2352. lpcwstrFullPathFileName [in] - The message full path name .
  2353. Folder [in] - Specifies if it is sent or received message.
  2354. lppUserSid [out] - Address of a pointer to SID to receive the user sid.
  2355. pdwlMessageId [out] - Address of a DWORDLONG to receive the message id.
  2356. Return Value:
  2357. BOOL
  2358. --*/
  2359. )
  2360. {
  2361. WCHAR wszUserSid[MAX_PATH] = {0};
  2362. LPCWSTR lpcwstrFileName = NULL;
  2363. DWORDLONG dwlMessageId;
  2364. DEBUG_FUNCTION_NAME(TEXT("GetSentMessageUserSid"));
  2365. Assert (lpcwstrFullPathFileName && (wcslen(lpcwstrFullPathFileName) < 2*MAX_PATH));
  2366. lpcwstrFileName = wcsrchr (lpcwstrFullPathFileName, L'\\');
  2367. if (NULL == lpcwstrFileName)
  2368. {
  2369. DebugPrintEx(
  2370. DEBUG_ERR,
  2371. TEXT("Bad file name (No '\\' delimitor found)"));
  2372. SetLastError (ERROR_INVALID_PARAMETER);
  2373. ASSERT_FALSE;
  2374. return FALSE;
  2375. }
  2376. lpcwstrFileName++;
  2377. if (FAX_MESSAGE_FOLDER_SENTITEMS == Folder)
  2378. {
  2379. if (2 != swscanf (lpcwstrFileName,
  2380. L"%[^'$']$%I64x.TIF",
  2381. wszUserSid,
  2382. &dwlMessageId))
  2383. {
  2384. DebugPrintEx(
  2385. DEBUG_ERR,
  2386. TEXT("Bad sent items file name"));
  2387. SetLastError (ERROR_BADDB);
  2388. return FALSE;
  2389. }
  2390. }
  2391. else
  2392. {
  2393. // Inbox
  2394. Assert (FAX_MESSAGE_FOLDER_INBOX == Folder);
  2395. if (1 != swscanf (lpcwstrFileName,
  2396. L"%I64x.TIF",
  2397. &dwlMessageId))
  2398. {
  2399. DebugPrintEx(
  2400. DEBUG_ERR,
  2401. TEXT("Bad inbox file name"));
  2402. SetLastError (ERROR_BADDB);
  2403. return FALSE;
  2404. }
  2405. }
  2406. if (NULL != lppUserSid)
  2407. {
  2408. Assert (FAX_MESSAGE_FOLDER_SENTITEMS == Folder);
  2409. if (!ConvertStringSidToSid (wszUserSid, lppUserSid))
  2410. {
  2411. DWORD dwRes = GetLastError();
  2412. DebugPrintEx(
  2413. DEBUG_ERR,
  2414. TEXT("ConvertStringSidToSid failed with %ld"), dwRes);
  2415. return FALSE;
  2416. }
  2417. }
  2418. if (NULL != pdwlMessageId)
  2419. {
  2420. *pdwlMessageId = dwlMessageId;
  2421. }
  2422. return TRUE;
  2423. }
  2424. BOOL
  2425. ArchiveAutoDelete(
  2426. LPCWSTR lpcwstrArchive,
  2427. DWORD dwAgeLimit,
  2428. FAX_ENUM_MESSAGE_FOLDER Folder
  2429. )
  2430. /*++
  2431. Routine name : ArchiveAutoDelete
  2432. Routine description:
  2433. Automatically deletes any files that are older than the age limit specified in days.
  2434. Author:
  2435. Oded Sacher (OdedS), Feb, 2000
  2436. Arguments:
  2437. lpcwstrArchive [in] - Full path to the archive folder to search for files to delete.
  2438. dwAgeLimit [in] - The files age limit specified in days, any file older than the limit will be deleted.
  2439. Folder [in] - Specifies if it is inbox or sent items folder
  2440. Return Value:
  2441. BOOL , Call GetLastError() for additional info.
  2442. --*/
  2443. {
  2444. DWORD dwRes = ERROR_NO_MORE_FILES;
  2445. DEBUG_FUNCTION_NAME(TEXT("ArchiveAutoDelete"));
  2446. WIN32_FIND_DATA FindFileData;
  2447. HANDLE hFind;
  2448. Assert (lpcwstrArchive && dwAgeLimit);
  2449. WCHAR szFileName[MAX_PATH*2] = {0};
  2450. BOOL bAnyDeleted = FALSE;
  2451. wsprintf( szFileName, TEXT("%s\\*.TIF"), lpcwstrArchive );
  2452. hFind = FindFirstFile( szFileName, &FindFileData );
  2453. if (hFind == INVALID_HANDLE_VALUE)
  2454. {
  2455. //
  2456. // No files found at archive dir
  2457. //
  2458. dwRes = GetLastError();
  2459. if (ERROR_FILE_NOT_FOUND != dwRes)
  2460. {
  2461. DebugPrintEx( DEBUG_WRN,
  2462. TEXT("FindFirstFile failed (ec = %ld) for archive dir %s"),
  2463. GetLastError(),
  2464. lpcwstrArchive);
  2465. return FALSE;
  2466. }
  2467. return TRUE;
  2468. }
  2469. do
  2470. {
  2471. //
  2472. // Get rid of old files
  2473. //
  2474. FILETIME CurrentTime;
  2475. DWORDLONG dwlAgeLimit, dwlCurrentTime, dwlFileTime;
  2476. GetSystemTimeAsFileTime (&CurrentTime);
  2477. dwlCurrentTime = MAKELONGLONG(CurrentTime.dwLowDateTime,
  2478. CurrentTime.dwHighDateTime);
  2479. dwlAgeLimit = MAKELONGLONG(dwAgeLimit, 0);
  2480. dwlAgeLimit = (dwlAgeLimit * 24 * 60 * 60 * 10000000);
  2481. dwlFileTime = MAKELONGLONG(FindFileData.ftCreationTime.dwLowDateTime,
  2482. FindFileData.ftCreationTime.dwHighDateTime);
  2483. if ( (dwlCurrentTime - dwlFileTime) > dwlAgeLimit)
  2484. {
  2485. // Old file - delete it
  2486. wsprintf( szFileName, TEXT("%s\\%s"), lpcwstrArchive, FindFileData.cFileName );
  2487. if (!DeleteFile (szFileName))
  2488. {
  2489. DebugPrintEx(
  2490. DEBUG_ERR,
  2491. TEXT("DeleteFile [FileName %s], Failed with %ld"),
  2492. szFileName,
  2493. GetLastError());
  2494. }
  2495. else
  2496. {
  2497. //
  2498. // Files were deleted - Send event to the registered clients
  2499. //
  2500. DWORD rVal = ERROR_SUCCESS;
  2501. PSID lpUserSid = NULL;
  2502. FAX_ENUM_EVENT_TYPE EventType;
  2503. DWORDLONG dwlMessageId;
  2504. PSID* lppUserSid = NULL;
  2505. bAnyDeleted = TRUE; // Refresh Archive size
  2506. if (FAX_MESSAGE_FOLDER_INBOX == Folder)
  2507. {
  2508. EventType = FAX_EVENT_TYPE_IN_ARCHIVE;
  2509. }
  2510. else
  2511. {
  2512. EventType = FAX_EVENT_TYPE_OUT_ARCHIVE;
  2513. lppUserSid = &lpUserSid;
  2514. }
  2515. if (!GetMessageIdAndUserSid (szFileName, Folder, lppUserSid, &dwlMessageId))
  2516. {
  2517. rVal = GetLastError();
  2518. DebugPrintEx(DEBUG_ERR,
  2519. TEXT("GetMessageIdAndUserSid Failed, Error : %ld"),
  2520. rVal);
  2521. }
  2522. if (ERROR_SUCCESS == rVal)
  2523. {
  2524. rVal = CreateArchiveEvent (dwlMessageId, EventType, FAX_JOB_EVENT_TYPE_REMOVED, lpUserSid);
  2525. if (ERROR_SUCCESS != rVal)
  2526. {
  2527. DebugPrintEx(
  2528. DEBUG_ERR,
  2529. TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_*_ARCHIVE) failed (ec: %lc)"),
  2530. rVal);
  2531. }
  2532. }
  2533. if (NULL != lpUserSid)
  2534. {
  2535. LocalFree (lpUserSid);
  2536. lpUserSid = NULL;
  2537. }
  2538. }
  2539. }
  2540. } while(FindNextFile( hFind, &FindFileData ));
  2541. dwRes = GetLastError();
  2542. if (ERROR_NO_MORE_FILES != dwRes)
  2543. {
  2544. DebugPrintEx( DEBUG_ERR,
  2545. TEXT("FindNextFilefaild with ec=%ld, at archive dir %s"),
  2546. dwRes,
  2547. lpcwstrArchive);
  2548. }
  2549. if (!FindClose(hFind))
  2550. {
  2551. DebugPrintEx( DEBUG_ERR,
  2552. TEXT("FindClose with ec=%ld, at archive dir %s"),
  2553. dwRes,
  2554. lpcwstrArchive);
  2555. }
  2556. if (TRUE == bAnyDeleted)
  2557. {
  2558. //
  2559. // Refresh archive size
  2560. //
  2561. EnterCriticalSection (&g_CsConfig);
  2562. g_ArchivesConfig[Folder].dwlArchiveSize = FAX_ARCHIVE_FOLDER_INVALID_SIZE;
  2563. LeaveCriticalSection (&g_CsConfig);
  2564. //
  2565. // Wake up quota warning thread
  2566. //
  2567. if (!SetEvent (g_hArchiveQuotaWarningEvent))
  2568. {
  2569. DebugPrintEx(
  2570. DEBUG_ERR,
  2571. TEXT("Failed to set quota warning event, SetEvent failed (ec: %lc)"),
  2572. GetLastError());
  2573. }
  2574. }
  2575. return (ERROR_NO_MORE_FILES == dwRes);
  2576. } //ArchiveAutoDelete
  2577. BOOL
  2578. GetArchiveSize(
  2579. LPCWSTR lpcwstrArchive,
  2580. DWORDLONG* lpdwlArchiveSize
  2581. )
  2582. /*++
  2583. Routine name : GetArchiveSize
  2584. Routine description:
  2585. Returnes the archive folder total size in bytes.
  2586. Author:
  2587. Oded Sacher (OdedS), Feb, 2000
  2588. Arguments:
  2589. lpcwstrArchive [in ] - Full path to the archive folder.
  2590. lpdwlArchiveSize [out] - Pointer to a DWORDLONG to receive the archive folder size.
  2591. Return Value:
  2592. BOOL , Call GetLastError() for additional info.
  2593. --*/
  2594. {
  2595. DWORD dwRes = ERROR_NO_MORE_FILES;
  2596. DEBUG_FUNCTION_NAME(TEXT("GetArchiveSize"));
  2597. WIN32_FIND_DATA FindFileData;
  2598. HANDLE hFind;
  2599. DWORDLONG dwlArchiveSize = 0;
  2600. Assert (lpcwstrArchive && lpdwlArchiveSize);
  2601. WCHAR szFileName[MAX_PATH*2] = {0};
  2602. wsprintf( szFileName, TEXT("%s\\*.*"), lpcwstrArchive );
  2603. hFind = FindFirstFile( szFileName, &FindFileData );
  2604. if (hFind == INVALID_HANDLE_VALUE)
  2605. {
  2606. //
  2607. // No files found at archive dir
  2608. //
  2609. DebugPrintEx( DEBUG_WRN,
  2610. TEXT("FindFirstFile failed (ec = %ld) for archive dir %s"),
  2611. GetLastError(),
  2612. lpcwstrArchive);
  2613. return FALSE;
  2614. }
  2615. do
  2616. {
  2617. dwlArchiveSize += (MAKELONGLONG(FindFileData.nFileSizeLow ,FindFileData.nFileSizeHigh));
  2618. } while(FindNextFile( hFind, &FindFileData ));
  2619. dwRes = GetLastError();
  2620. if (ERROR_NO_MORE_FILES != dwRes)
  2621. {
  2622. DebugPrintEx( DEBUG_ERR,
  2623. TEXT("FindNextFilefaild with ec=%ld, at archive dir %s"),
  2624. dwRes,
  2625. lpcwstrArchive);
  2626. }
  2627. if (!FindClose(hFind))
  2628. {
  2629. DebugPrintEx( DEBUG_ERR,
  2630. TEXT("FindClose with ec=%ld, at archive dir %s"),
  2631. dwRes,
  2632. lpcwstrArchive);
  2633. }
  2634. if (ERROR_NO_MORE_FILES == dwRes)
  2635. {
  2636. *lpdwlArchiveSize = dwlArchiveSize;
  2637. return TRUE;
  2638. }
  2639. return FALSE;
  2640. } //GetArchiveSize
  2641. DWORD
  2642. FaxArchiveQuotaWarningThread(
  2643. LPVOID UnUsed
  2644. )
  2645. /*++
  2646. Routine Description:
  2647. This fuction runs as a separate thread to
  2648. watch the archives quota and send event to the event log
  2649. Arguments:
  2650. UnUsed - UnUsed pointer
  2651. Return Value:
  2652. Always zero.
  2653. --*/
  2654. {
  2655. DEBUG_FUNCTION_NAME(TEXT("FaxArchiveQuotaWarningThread"));
  2656. DWORD dwCount[2] = {QUOTA_REFRESH_COUNT, QUOTA_REFRESH_COUNT};
  2657. HANDLE Handles[2];
  2658. Assert (g_hArchiveQuotaWarningEvent && g_hServiceShutDownEvent);
  2659. Handles[0] = g_hArchiveQuotaWarningEvent;
  2660. Handles[1] = g_hServiceShutDownEvent;
  2661. for (;;)
  2662. {
  2663. for (DWORD i = 0; i < 2; i++)
  2664. {
  2665. WCHAR wszArchive[MAX_PATH] = {0};
  2666. DWORDLONG dwlArchiveSize;
  2667. DWORDLONG dwlHighMark, dwlLowMark;
  2668. BOOL bLoggedQuotaEvent;
  2669. EnterCriticalSection (&g_CsConfig);
  2670. if (TRUE == g_ArchivesConfig[i].bUseArchive &&
  2671. TRUE == g_ArchivesConfig[i].bSizeQuotaWarning)
  2672. {
  2673. //
  2674. // The user asked for archive monitoring
  2675. //
  2676. Assert (g_ArchivesConfig[i].lpcstrFolder);
  2677. dwlHighMark = MAKELONGLONG(g_ArchivesConfig[i].dwSizeQuotaHighWatermark, 0);
  2678. dwlHighMark = (dwlHighMark << 20); // convert MB to bytes
  2679. dwlLowMark = MAKELONGLONG(g_ArchivesConfig[i].dwSizeQuotaLowWatermark, 0);
  2680. dwlLowMark = (dwlLowMark << 20); // convert MB to bytes
  2681. wcscpy (wszArchive, g_ArchivesConfig[i].lpcstrFolder);
  2682. bLoggedQuotaEvent = g_FaxQuotaWarn[i].bLoggedQuotaEvent;
  2683. dwlArchiveSize = g_ArchivesConfig[i].dwlArchiveSize;
  2684. g_FaxQuotaWarn[i].bConfigChanged = FALSE; // We will check this flag if we need to update g_ArchivesConfig
  2685. }
  2686. else
  2687. {
  2688. // do not warn
  2689. LeaveCriticalSection (&g_CsConfig);
  2690. continue;
  2691. }
  2692. LeaveCriticalSection (&g_CsConfig);
  2693. // The client asked for quota warnings
  2694. //
  2695. // Compare archive size and water mark
  2696. //
  2697. if (FAX_ARCHIVE_FOLDER_INVALID_SIZE == dwlArchiveSize ||
  2698. dwCount[i] >= QUOTA_REFRESH_COUNT)
  2699. {
  2700. //
  2701. // We want to refresh the archive size
  2702. //
  2703. //
  2704. // Check if service is going down before starting to delete
  2705. //
  2706. if (TRUE == g_bServiceIsDown)
  2707. {
  2708. //
  2709. // Server is shutting down - Do not refresh archives size
  2710. //
  2711. DebugPrintEx(
  2712. DEBUG_WRN,
  2713. TEXT("Server is shutting down - Do not refresh archives size"));
  2714. break;
  2715. }
  2716. if (!GetArchiveSize (wszArchive, &dwlArchiveSize))
  2717. {
  2718. DebugPrintEx( DEBUG_ERR,
  2719. TEXT("GetArchiveSize with ec=%ld, at archive dir %s"),
  2720. GetLastError(),
  2721. wszArchive);
  2722. continue;
  2723. }
  2724. else
  2725. {
  2726. // Update folder size
  2727. EnterCriticalSection (&g_CsConfig);
  2728. if (FALSE == g_FaxQuotaWarn[i].bConfigChanged)
  2729. {
  2730. // The configuration did not change - we can update g_ArchivesConfig
  2731. g_ArchivesConfig[i].dwlArchiveSize = dwlArchiveSize;
  2732. }
  2733. LeaveCriticalSection (&g_CsConfig);
  2734. dwCount[i] = 0;
  2735. }
  2736. }
  2737. if (FALSE == bLoggedQuotaEvent)
  2738. {
  2739. //We did not logged an archive quota warning yet
  2740. if (dwlArchiveSize > dwlHighMark)
  2741. {
  2742. //
  2743. // Create event log
  2744. //
  2745. if (FAX_MESSAGE_FOLDER_INBOX == i)
  2746. {
  2747. DWORD dwHighMark = (DWORD)(dwlHighMark >> 20); // size in MB
  2748. FaxLog(
  2749. FAXLOG_CATEGORY_INBOUND,
  2750. FAXLOG_LEVEL_MED,
  2751. 2,
  2752. MSG_FAX_EXEEDED_INBOX_QUOTA,
  2753. wszArchive,
  2754. DWORD2DECIMAL(dwHighMark)
  2755. );
  2756. }
  2757. else
  2758. {
  2759. Assert (FAX_MESSAGE_FOLDER_SENTITEMS == i);
  2760. DWORD dwHighMark = (DWORD)(dwlHighMark >> 20); // size in MB
  2761. FaxLog(
  2762. FAXLOG_CATEGORY_OUTBOUND,
  2763. FAXLOG_LEVEL_MED,
  2764. 2,
  2765. MSG_FAX_EXEEDED_SENTITEMS_QUOTA,
  2766. wszArchive,
  2767. DWORD2DECIMAL(dwHighMark)
  2768. );
  2769. }
  2770. EnterCriticalSection (&g_CsConfig);
  2771. if (FALSE == g_FaxQuotaWarn[i].bConfigChanged)
  2772. {
  2773. // The configuration did not change - we can update g_ArchivesConfig
  2774. g_FaxQuotaWarn[i].bLoggedQuotaEvent = TRUE;
  2775. }
  2776. LeaveCriticalSection (&g_CsConfig);
  2777. }
  2778. }
  2779. else
  2780. {
  2781. // An archive quota warning was already logged
  2782. if (dwlArchiveSize < dwlLowMark)
  2783. {
  2784. EnterCriticalSection (&g_CsConfig);
  2785. if (FALSE == g_FaxQuotaWarn[i].bConfigChanged)
  2786. {
  2787. // The configuration did not change - we can update g_ArchivesConfig
  2788. g_FaxQuotaWarn[i].bLoggedQuotaEvent = FALSE;
  2789. }
  2790. LeaveCriticalSection (&g_CsConfig);
  2791. }
  2792. }
  2793. dwCount[i] ++;
  2794. } // end of for loop
  2795. DWORD dwWaitRes = WaitForMultipleObjects( 2, Handles, FALSE, QUOTA_WARNING_TIME_OUT);
  2796. if (WAIT_FAILED == dwWaitRes)
  2797. {
  2798. DebugPrintEx(
  2799. DEBUG_ERR,
  2800. TEXT("WaitForMultipleObjects() failed, (LastErorr: %ld)"),
  2801. GetLastError());
  2802. }
  2803. else
  2804. {
  2805. DebugPrintEx(
  2806. DEBUG_MSG,
  2807. TEXT("WaitForMultipleObjects() returned Wait result: %ld)"),
  2808. dwWaitRes);
  2809. }
  2810. if ((dwWaitRes - WAIT_OBJECT_0) == 1)
  2811. {
  2812. //
  2813. // We got the service shut down event
  2814. //
  2815. DebugPrintEx(
  2816. DEBUG_MSG,
  2817. TEXT("Service is shutting down"));
  2818. break;
  2819. }
  2820. } // end of outer for(;;) loop
  2821. if (!DecreaseServiceThreadsCount())
  2822. {
  2823. DebugPrintEx(
  2824. DEBUG_ERR,
  2825. TEXT("DecreaseServiceThreadsCount() failed (ec: %ld)"),
  2826. GetLastError());
  2827. }
  2828. return ERROR_SUCCESS;
  2829. } // FaxArchiveQuotaWarningThread
  2830. DWORD
  2831. FaxArchiveQuotaAutoDeleteThread(
  2832. LPVOID UnUsed
  2833. )
  2834. /*++
  2835. Routine Description:
  2836. This fuction runs as a separate thread to
  2837. watch the archives quota and automaticlly delete old files
  2838. Arguments:
  2839. UnUsed - UnUsed pointer
  2840. Return Value:
  2841. Always zero.
  2842. --*/
  2843. {
  2844. DEBUG_FUNCTION_NAME(TEXT("FaxArchiveQuotaAutoDeleteThread"));
  2845. Assert(g_hServiceShutDownEvent);
  2846. for (;;)
  2847. {
  2848. for (DWORD i = 0; i < 2; i++)
  2849. {
  2850. WCHAR wszArchive[MAX_PATH] = {0};
  2851. DWORD dwAgeLimit;
  2852. EnterCriticalSection (&g_CsConfig);
  2853. if (TRUE == g_ArchivesConfig[i].bUseArchive &&
  2854. 0 != g_ArchivesConfig[i].dwAgeLimit)
  2855. {
  2856. //
  2857. // The user asked for archive auto delete
  2858. //
  2859. Assert (g_ArchivesConfig[i].lpcstrFolder);
  2860. wcscpy (wszArchive, g_ArchivesConfig[i].lpcstrFolder);
  2861. dwAgeLimit = g_ArchivesConfig[i].dwAgeLimit;
  2862. }
  2863. else
  2864. {
  2865. // Do not auto delete
  2866. LeaveCriticalSection (&g_CsConfig);
  2867. continue;
  2868. }
  2869. LeaveCriticalSection (&g_CsConfig);
  2870. //
  2871. // Check if service is going down before starting to delete
  2872. //
  2873. if (TRUE == g_bServiceIsDown)
  2874. {
  2875. //
  2876. // Server is shutting down - Do not auto delete archives
  2877. //
  2878. DebugPrintEx(
  2879. DEBUG_WRN,
  2880. TEXT("Server is shutting down - Do not auto delete archives"));
  2881. break;
  2882. }
  2883. if (!ArchiveAutoDelete (wszArchive, dwAgeLimit, (FAX_ENUM_MESSAGE_FOLDER)i))
  2884. {
  2885. DWORD dwRes = GetLastError();
  2886. DebugPrintEx( DEBUG_ERR,
  2887. TEXT("ArchiveAutoDelete with ec=%ld, at archive dir %s"),
  2888. dwRes,
  2889. wszArchive);
  2890. }
  2891. } // end of inner for loop
  2892. DWORD dwWaitRes = WaitForSingleObject( g_hServiceShutDownEvent, QUOTA_AUTO_DELETE_TIME_OUT);
  2893. if (WAIT_FAILED == dwWaitRes)
  2894. {
  2895. DebugPrintEx(
  2896. DEBUG_ERR,
  2897. TEXT("WaitForSingleObject() failed, (LastErorr: %ld)"),
  2898. GetLastError());
  2899. }
  2900. else
  2901. {
  2902. DebugPrintEx(
  2903. DEBUG_MSG,
  2904. TEXT("WaitForSingleObject() returned Wait result: %ld)"),
  2905. dwWaitRes);
  2906. }
  2907. if (WAIT_OBJECT_0 == dwWaitRes)
  2908. {
  2909. //
  2910. // We got the service shut down event
  2911. //
  2912. DebugPrintEx(
  2913. DEBUG_MSG,
  2914. TEXT("Service is shutting down"));
  2915. break;
  2916. }
  2917. } // end of outer for loop
  2918. if (!DecreaseServiceThreadsCount())
  2919. {
  2920. DebugPrintEx(
  2921. DEBUG_ERR,
  2922. TEXT("DecreaseServiceThreadsCount() failed (ec: %ld)"),
  2923. GetLastError());
  2924. }
  2925. return ERROR_SUCCESS;
  2926. } // FaxArchiveQuotaAutoDeleteThread
  2927. DWORD
  2928. InitializeServerQuota ()
  2929. /*++
  2930. Routine name : InitializeServerQuota
  2931. Routine description:
  2932. Creates the threads that watches the archives quota
  2933. Author:
  2934. Oded Sacher (OdedS), Jan, 2000
  2935. Arguments:
  2936. Return Value:
  2937. Standard Win32 error code
  2938. --*/
  2939. {
  2940. DWORD dwRes = ERROR_SUCCESS;
  2941. DEBUG_FUNCTION_NAME(TEXT("InitializeServerQuota"));
  2942. DWORD ThreadId;
  2943. HANDLE hQuotaWarningThread = NULL;
  2944. HANDLE hQuotaAutoDeleteThread = NULL;
  2945. //
  2946. // Create Archive Config events
  2947. //
  2948. g_hArchiveQuotaWarningEvent = CreateEvent( NULL, // Secutity descriptor
  2949. FALSE, // flag for manual-reset event
  2950. FALSE, // flag for initial state
  2951. NULL // pointer to event-object name
  2952. );
  2953. if (NULL == g_hArchiveQuotaWarningEvent)
  2954. {
  2955. dwRes = GetLastError();
  2956. DebugPrintEx(
  2957. DEBUG_ERR,
  2958. TEXT("Failed to create archive config event - quota warning (CreateEvent) (ec=0x%08x)."),
  2959. dwRes);
  2960. goto exit;
  2961. }
  2962. //
  2963. // Initialize Archive folders sizes
  2964. //
  2965. Assert (g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder);
  2966. g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].dwlArchiveSize = FAX_ARCHIVE_FOLDER_INVALID_SIZE;
  2967. if (TRUE == g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].bUseArchive)
  2968. {
  2969. //
  2970. // Archive is in use
  2971. //
  2972. //
  2973. // Check archive folder validity
  2974. //
  2975. DWORD dwRet = IsValidArchiveFolder(g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder,FAX_MESSAGE_FOLDER_INBOX);
  2976. if(ERROR_SUCCESS != dwRet)
  2977. {
  2978. //
  2979. // The folder is not valid for archiving
  2980. //
  2981. DebugPrintEx( DEBUG_ERR,
  2982. TEXT("IsValidArchiveFolder failed for folder : %s (ec=%lu)."),
  2983. g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder,
  2984. dwRet);
  2985. //
  2986. // Log event and disable - receive and routing activity - for inbox
  2987. //
  2988. FaxLog( FAXLOG_CATEGORY_INIT,
  2989. FAXLOG_LEVEL_MIN,
  2990. 1,
  2991. MSG_FAX_ARCHIVE_INBOX_FOLDER_ERR,
  2992. g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder,
  2993. DWORD2DECIMAL(dwRet)
  2994. );
  2995. EnterCriticalSection (&g_CsConfig);
  2996. g_dwQueueState |= FAX_INCOMING_BLOCKED;
  2997. LeaveCriticalSection (&g_CsConfig);
  2998. }
  2999. else
  3000. if (!GetArchiveSize (g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder, &g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].dwlArchiveSize))
  3001. {
  3002. DebugPrintEx( DEBUG_ERR,
  3003. TEXT("GetArchiveSize with ec=%ld, at archive dir %s"),
  3004. GetLastError(),
  3005. g_ArchivesConfig[FAX_MESSAGE_FOLDER_INBOX].lpcstrFolder);
  3006. }
  3007. }
  3008. Assert (g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder);
  3009. g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].dwlArchiveSize = FAX_ARCHIVE_FOLDER_INVALID_SIZE;
  3010. if (TRUE == g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].bUseArchive)
  3011. {
  3012. //
  3013. // Archive is in use
  3014. //
  3015. //
  3016. // Check archive folder validity
  3017. //
  3018. DWORD dwRet = IsValidArchiveFolder(g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder,FAX_MESSAGE_FOLDER_SENTITEMS);
  3019. if(ERROR_SUCCESS != dwRet)
  3020. {
  3021. //
  3022. // The folder is not valid for archiving
  3023. //
  3024. DebugPrintEx( DEBUG_ERR,
  3025. TEXT("IsValidArchiveFolder failed for folder : %s (ec=%lu)."),
  3026. g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder,
  3027. dwRet);
  3028. //
  3029. // Log event and disable - submission and send activity - for outbox
  3030. //
  3031. FaxLog( FAXLOG_CATEGORY_INIT,
  3032. FAXLOG_LEVEL_MIN,
  3033. 1,
  3034. MSG_FAX_ARCHIVE_OUTBOX_FOLDER_ERR,
  3035. g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder
  3036. );
  3037. EnterCriticalSection (&g_CsConfig);
  3038. g_dwQueueState |= FAX_OUTBOX_BLOCKED | FAX_OUTBOX_PAUSED;
  3039. LeaveCriticalSection (&g_CsConfig);
  3040. }
  3041. else
  3042. if (!GetArchiveSize (g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder, &g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].dwlArchiveSize))
  3043. {
  3044. DebugPrintEx( DEBUG_ERR,
  3045. TEXT("GetArchiveSize with ec=%ld, at archive dir %s"),
  3046. GetLastError(),
  3047. g_ArchivesConfig[FAX_MESSAGE_FOLDER_SENTITEMS].lpcstrFolder);
  3048. }
  3049. }
  3050. //
  3051. // Create the archives quata warning thread
  3052. //
  3053. hQuotaWarningThread = CreateThreadAndRefCount(
  3054. NULL,
  3055. 0,
  3056. (LPTHREAD_START_ROUTINE) FaxArchiveQuotaWarningThread,
  3057. NULL,
  3058. 0,
  3059. &ThreadId
  3060. );
  3061. if (!hQuotaWarningThread)
  3062. {
  3063. dwRes = GetLastError();
  3064. DebugPrintEx(
  3065. DEBUG_ERR,
  3066. TEXT("Failed to create quota warning thread (CreateThreadAndRefCount) (ec=0x%08x)."),
  3067. dwRes);
  3068. goto exit;
  3069. }
  3070. //
  3071. // Create the archives quata auto delete thread
  3072. //
  3073. hQuotaAutoDeleteThread = CreateThreadAndRefCount(
  3074. NULL,
  3075. 0,
  3076. (LPTHREAD_START_ROUTINE) FaxArchiveQuotaAutoDeleteThread,
  3077. NULL,
  3078. 0,
  3079. &ThreadId
  3080. );
  3081. if (!hQuotaAutoDeleteThread)
  3082. {
  3083. dwRes = GetLastError();
  3084. DebugPrintEx(
  3085. DEBUG_ERR,
  3086. TEXT("Failed to create quota auto delete thread (CreateThreadAndRefCount) (ec=0x%08x)."),
  3087. dwRes);
  3088. goto exit;
  3089. }
  3090. Assert (ERROR_SUCCESS == dwRes);
  3091. exit:
  3092. //
  3093. // Close the thread handle we no longer need it
  3094. //
  3095. if (NULL != hQuotaWarningThread)
  3096. {
  3097. if (!CloseHandle(hQuotaWarningThread))
  3098. {
  3099. DebugPrintEx(
  3100. DEBUG_ERR,
  3101. TEXT("Failed to close quota warning thread handle [handle = %p] (ec=0x%08x)."),
  3102. hQuotaWarningThread,
  3103. GetLastError());
  3104. }
  3105. }
  3106. if (NULL != hQuotaAutoDeleteThread)
  3107. {
  3108. if (!CloseHandle(hQuotaAutoDeleteThread))
  3109. {
  3110. DebugPrintEx(
  3111. DEBUG_ERR,
  3112. TEXT("Failed to close quota auto delete thread handle [handle = %p] (ec=0x%08x)."),
  3113. hQuotaAutoDeleteThread,
  3114. GetLastError());
  3115. }
  3116. }
  3117. if (ERROR_SUCCESS != dwRes)
  3118. {
  3119. if (NULL != g_hArchiveQuotaWarningEvent)
  3120. {
  3121. if (!CloseHandle(g_hArchiveQuotaWarningEvent))
  3122. {
  3123. DebugPrintEx(
  3124. DEBUG_ERR,
  3125. TEXT("Failed to close archive config event handle - quota warnings [handle = %p] (ec=0x%08x)."),
  3126. g_hArchiveQuotaWarningEvent,
  3127. GetLastError());
  3128. }
  3129. g_hArchiveQuotaWarningEvent = NULL;
  3130. }
  3131. }
  3132. return dwRes;
  3133. } // InitializeServerQuota