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.

202 lines
5.3 KiB

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "seo.h"
  4. #include "nntpfilt.h"
  5. #include "ddrop.h"
  6. #include "filter.h"
  7. #include <stdio.h>
  8. #include "mailmsgprops.h"
  9. HRESULT CNNTPDirectoryDrop::FinalConstruct() {
  10. *m_wszDropDirectory = 0;
  11. return (CoCreateFreeThreadedMarshaler(GetControllingUnknown(),
  12. &m_pUnkMarshaler.p));
  13. }
  14. void CNNTPDirectoryDrop::FinalRelease() {
  15. m_pUnkMarshaler.Release();
  16. }
  17. BOOL
  18. AddTerminatedDot(
  19. HANDLE hFile
  20. )
  21. /*++
  22. Description:
  23. Add the terminated dot
  24. Argument:
  25. hFile - file handle
  26. Return Value:
  27. TRUE if successful, FALSE otherwise
  28. --*/
  29. {
  30. TraceFunctEnter( "CNntpFSDriver::AddTerminatedDot" );
  31. DWORD ret = NO_ERROR;
  32. // SetFilePointer to move the EOF file pointer
  33. ret = SetFilePointer( hFile,
  34. 5, // move file pointer 5 chars more, CRLF.CRLF,...
  35. NULL,
  36. FILE_END ); // ...from EOF
  37. if (ret == 0xFFFFFFFF)
  38. {
  39. ret = GetLastError();
  40. ErrorTrace(0, "SetFilePointer() failed - %d\n", ret);
  41. return FALSE;
  42. }
  43. // pickup the length of the file
  44. DWORD cb = ret;
  45. // Call SetEndOfFile to actually set the file pointer
  46. if (!SetEndOfFile( hFile ))
  47. {
  48. ret = GetLastError();
  49. ErrorTrace(0, "SetEndOfFile() failed - %d\n", ret);
  50. return FALSE;
  51. }
  52. // Write terminating dot sequence
  53. static char szTerminator[] = "\r\n.\r\n" ;
  54. DWORD cbOut = 0;
  55. OVERLAPPED ovl;
  56. ovl.Offset = cb - 5;
  57. ovl.OffsetHigh = 0;
  58. HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  59. if (hEvent == NULL)
  60. {
  61. ErrorTrace(0, "CreateEvent() failed - %d\n", GetLastError());
  62. return FALSE;
  63. }
  64. ovl.hEvent = (HANDLE)(((DWORD_PTR)hEvent) | 0x1);
  65. if (! WriteFile( hFile, szTerminator, 5, &cbOut, &ovl ))
  66. {
  67. ret = GetLastError();
  68. if (ret == ERROR_IO_PENDING)
  69. {
  70. WaitForSingleObject( hEvent, INFINITE );
  71. }
  72. else
  73. {
  74. ErrorTrace(0, "WriteFile() failed - %d\n", ret);
  75. _VERIFY( CloseHandle(hEvent) );
  76. return FALSE;
  77. }
  78. }
  79. if (hEvent != 0) {
  80. _VERIFY( CloseHandle(hEvent) );
  81. }
  82. return TRUE;
  83. }
  84. //
  85. // this is our filter function.
  86. //
  87. HRESULT STDMETHODCALLTYPE CNNTPDirectoryDrop::OnPost(IMailMsgProperties *pMsg) {
  88. HRESULT hr;
  89. #if 0
  90. // if this code is enabled then the post will be cancelled
  91. pMsg->PutDWORD(IMMPID_NMP_NNTP_PROCESSING, 0x0);
  92. #endif
  93. _ASSERT(pMsg != NULL);
  94. if (pMsg == NULL) return E_INVALIDARG;
  95. HANDLE hFile;
  96. WCHAR szDestFilename[MAX_PATH];
  97. if (*m_wszDropDirectory == 0) {
  98. return E_INVALIDARG;
  99. }
  100. // get a temp filename to write to
  101. // we use GetTickCount() to generate the base of the filename. This is
  102. // to increase the number of temporary file names available (by default
  103. // GetTempFileName() only generated 65k of them, which fills up quickly
  104. // if nothing is picking up the dropped articles).
  105. WCHAR wszPrefix[12];
  106. wsprintfW(wszPrefix, L"d%02x", GetTickCount() & 0xff);
  107. wszPrefix[3] = 0;
  108. if (GetTempFileNameW(m_wszDropDirectory, wszPrefix, 0, szDestFilename) == 0) {
  109. return HRESULT_FROM_WIN32(GetLastError());
  110. }
  111. // open the destination file
  112. hFile = CreateFileW(szDestFilename, GENERIC_READ | GENERIC_WRITE,
  113. 0, NULL, OPEN_EXISTING,
  114. FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  115. if (hFile == INVALID_HANDLE_VALUE) {
  116. DeleteFileW(szDestFilename);
  117. return HRESULT_FROM_WIN32(GetLastError());
  118. }
  119. PFIO_CONTEXT pFIOContext = AssociateFileEx( hFile,
  120. TRUE, // fStoreWithDots
  121. TRUE // fStoreWithTerminatingDots
  122. );
  123. if (pFIOContext == NULL) {
  124. CloseHandle(hFile);
  125. DeleteFileW(szDestFilename);
  126. return HRESULT_FROM_WIN32(GetLastError());
  127. }
  128. // copy from the source stream to the destination file
  129. hr = pMsg->CopyContentToFileEx( pFIOContext,
  130. TRUE,
  131. NULL);
  132. //
  133. // Handle the trailing dot
  134. //
  135. if ( !GetIsFileDotTerminated( pFIOContext ) ) {
  136. // No dot, add it
  137. AddTerminatedDot( pFIOContext->m_hFile );
  138. // Set pFIOContext to has dot
  139. SetIsFileDotTerminated( pFIOContext, TRUE );
  140. }
  141. #if 0
  142. //
  143. // if this code is enabled then more properties will be dropped into the
  144. // file
  145. //
  146. SetFilePointer(hFile, 0, 0, FILE_END);
  147. BYTE buf[4096];
  148. DWORD c, dw;
  149. strcpy((char *) buf, "\r\n-------------\r\nheaders = "); c = strlen((char *)buf);
  150. WriteFile(hFile, buf, c, &dw, NULL);
  151. pMsg->GetProperty(IMMPID_NMP_HEADERS, 4096, &c, buf);
  152. WriteFile(hFile, buf, c, &dw, NULL);
  153. strcpy((char *) buf, "\r\n------------\r\nnewsgroups = "); c = strlen((char *)buf);
  154. WriteFile(hFile, buf, c, &dw, NULL);
  155. pMsg->GetProperty(IMMPID_NMP_NEWSGROUP_LIST, 4096, &c, buf);
  156. WriteFile(hFile, buf, c, &dw, NULL);
  157. strcpy((char *) buf, "\r\n------------\r\n"); c = strlen((char *)buf);
  158. WriteFile(hFile, buf, c, &dw, NULL);
  159. #endif
  160. // cleanup
  161. ReleaseContext(pFIOContext);
  162. if (!FAILED(hr)) hr = S_OK;
  163. return (hr);
  164. }