home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //
- // File Name
- // RXPRPC.CPP
- //
- // Description
- // This file implements all the remote functions available to client
- // WINDS message transport providers.
- //
- // Authors
- // Irving De la Cruz
- // Les Thaler
- //
- // Revision: 1.7
- //
- // Written for Microsoft Windows Developer Support
- // Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
- //
- #include "_WINDS.H"
- #include <RPC.H>
- #include "WINDS.H" // Header file generated by the MIDL compiler
- #include "WDSADM.H" // Header file generated by the MIDL compiler
-
- typedef struct tagTHREAD_PROC_INFO
- {
- HANDLE hPipe;
- HANDLE hTmpFile;
- TCHAR szTmpFile[MAX_PATH];
- TCHAR szMailbox[MAX_ALIAS_SIZE+1];
- } THREAD_PROC_INFO, *PTHREAD_PROC_INFO;
-
- typedef struct tagDL_DELIVERY_PROC_INFO
- {
- TCHAR szTmpFile[MAX_PATH];
- TCHAR szHeader[1024];
- DIST_LIST_INFO DLInfo;
- DWORD dwAliasDelivered;
- LPTSTR * ppszAliasList;
- HANDLE hWaitEvent;
- HANDLE hFile;
- BOOL fDeleteInfoStruct;
- } DL_DELIVERY_PROC_INFO, *PDL_DELIVERY_PROC_INFO;
-
- extern "C"
- {
- HRESULT WINAPI MsgUploadPipeThread
- (PTHREAD_PROC_INFO pInfo);
- HRESULT WINAPI MsgDownloadThread
- (PTHREAD_PROC_INFO pInfo);
- HRESULT WINAPI OneMsgDownloadPipeThread
- (PTHREAD_PROC_INFO pInfo);
- HRESULT WINAPI HeaderDLPipeThread
- (PTHREAD_PROC_INFO pInfo);
- DWORD WINAPI DistListDeliveryThread
- (PDL_DELIVERY_PROC_INFO pDLInfo);
- BOOL WINAPI DeleteMessage
- (HANDLE hResumeEvt,
- LPTSTR szMBox,
- LPBYTE pEID);
- HANDLE WINAPI OpenMessage
- (HANDLE hResumeEvt,
- LPTSTR pszMailBox,
- LPBYTE pEID,
- ULONG ulCmd,
- ULONG * pulMsgLen);
- HRESULT WINAPI ObjectDelivered
- (PDL_DELIVERY_PROC_INFO pInfo,
- LPTSTR szObject);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteOpenMsgUploadPipeA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteOpenMsgUploadPipeA (unsigned char * szSenderMailbox,
- long * pPipeNumber,
- unsigned char * szCookie)
- {
- LPTSTR pStrTok;
- TCHAR szBuffer[_MAX_PATH];
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- DWORD dwMailboxID;
- if (S_OK != GlobalObjectMap.FindObjFromName (SERVER_USER_MAILBOX, (LPSTR)szSenderMailbox, &dwMailboxID))
- {
- TraceMessage ("RemoteOpenUploadPipeA: The originator no longer has an account in this server");
- return HRESULT_FROM_WIN32(ERROR_NO_SUCH_USER);
- }
-
- PTHREAD_PROC_INFO pInfo = (PTHREAD_PROC_INFO)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(THREAD_PROC_INFO));
- if (NULL == pInfo)
- {
- TraceMessage ("RemoteOpenMsgUploadPipeA: Failed to allocate info structure");
- return E_OUTOFMEMORY;
- }
-
- lResult = GetLocalTempFileName (szBuffer);
- if (lResult)
- {
- goto TerminateAndCleanup;
- }
- lstrcpy (pInfo->szTmpFile, szBuffer);
- pInfo->hTmpFile = CreateFile (szBuffer,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (INVALID_HANDLE_VALUE == pInfo->hTmpFile)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgUploadPipeA: Failed to create the temp file", lResult);
- goto TerminateAndCleanup;
- }
-
- pStrTok = &szBuffer[lstrlen(szBuffer)];
- while ('\\' != *pStrTok)
- {
- pStrTok--;
- }
- pStrTok++;
- lstrcpy ((LPSTR)szCookie, pStrTok);
-
- *pPipeNumber = GetNextPipeID();
-
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
- // Initialize the new security descriptor.
- InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
-
- // Add a NULL descriptor ACL to the security descriptor.
- SetSecurityDescriptorDacl (&sd, TRUE, (PACL)NULL, FALSE);
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = TRUE;
-
- // Create a pipe where we will expect the transport to send the data
- wsprintf (szBuffer, SERVER_PIPE_NAME_FORMAT, *pPipeNumber);
- pInfo->hPipe = CreateNamedPipe (szBuffer,
- PIPE_ACCESS_INBOUND,
- PIPE_WAIT | PIPE_READMODE_BYTE | PIPE_TYPE_BYTE,
- 1,
- IO_BUFFERSIZE,
- IO_BUFFERSIZE,
- 0,
- &sa);
- if (INVALID_HANDLE_VALUE == pInfo->hPipe || ERROR_INVALID_PARAMETER == (DWORD)pInfo->hPipe)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgUploadPipeA: Failed to create pipe", lResult);
- }
- else
- {
- DWORD dwThreadID;
- HANDLE hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)MsgUploadPipeThread,
- (LPVOID)pInfo,
- 0,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("RemoteOpenMsgUploadPipeA: Message Upload thread spawned. ID: %X", dwThreadID);
- CloseHandle (hThread);
- pInfo = NULL; // The thread will free this memory
- }
- else
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgUploadPipeA: Failed to create pipe thread", lResult);
- }
- }
- TerminateAndCleanup :
- if (pInfo)
- {
- if (pInfo->hTmpFile && (ERROR_INVALID_HANDLE != (DWORD)pInfo->hTmpFile))
- {
- CloseHandle (pInfo->hTmpFile);
- }
- if (pInfo->hPipe)
- {
- CloseHandle (pInfo->hPipe);
- }
- HeapFree (ghHeap, 0, pInfo);
- }
- if (lResult)
- {
- if (FACILITY_NULL == HRESULT_FACILITY(lResult))
- {
- lResult = HRESULT_FROM_WIN32 (lResult);
- }
- }
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteSendMsgToAccountA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteSendMsgToAccountA (unsigned char * szRecipAccount,
- unsigned char * szHeaderInfo,
- unsigned char * szCookie)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- DWORD dwMailboxID;
- WINDS_AB_OBJTYPE Type;
- if (S_OK != GlobalObjectMap.FindObjAndTypeFromName ((LPSTR)szRecipAccount, &Type, &dwMailboxID))
- {
- TraceMessage ("RemoteSendMsgToAccountA: Rejecting message for an non-existing recipient");
- return HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME);
- }
-
- TCHAR szTmpPath[_MAX_PATH];
- if (!GetTempPath (_MAX_PATH, szTmpPath))
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteSendMsgToAccountA: Failed to get temp path", lResult);
- return HRESULT_FROM_WIN32 (lResult);
- }
-
- lstrcat (szTmpPath, (LPSTR)szCookie);
- PTHREAD_PROC_INFO pInfo = NULL;
- PDL_DELIVERY_PROC_INFO pDLInfo = NULL;
- HANDLE hFile = NULL, hWaitEvent;
- RetryOpenFile:
- hFile = CreateFile (szTmpPath,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- if (HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) == lResult)
- {
- lResult = S_OK;
- TraceMessage ("RemoteSendMsgToAccountA: Sharing Violation, waiting before retry");
- SleepEx (200, FALSE);
- goto RetryOpenFile;
- }
- TraceResult ("RemoteSendMsgToAccountA: Failed to open the temp file", lResult);
- return lResult;
- }
- hWaitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!hWaitEvent)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteSendMsgToAccountA: Failed to create event for I/O thread", lResult);
- goto ErrorExit;
- }
- if (SERVER_USER_MAILBOX == Type)
- {
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, (LPSTR)szRecipAccount);
- lstrcpy (g_IOInfo.szHeader, (LPSTR)szHeaderInfo);
- g_IOInfo.Action = IO_COPY_MSG_FROM_FILE;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.hTmpFile = hFile;
- g_IOInfo.fCloseHandle = TRUE;
- hFile = NULL;
- g_IOInfo.phLastError = &lResult;
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- }
- else
- {
- if (SERVER_DISTRIBUTION_LIST == Type)
- {
- pDLInfo = (PDL_DELIVERY_PROC_INFO)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(DL_DELIVERY_PROC_INFO));
- if (NULL == pDLInfo)
- {
- TraceMessage ("RemoteSendMsgToAccountA: Failed to allocate info structure");
- lResult = E_OUTOFMEMORY;
- goto ErrorExit;
- }
- pDLInfo->fDeleteInfoStruct = TRUE;
- lstrcpy (pDLInfo->DLInfo.szDLAlias, (LPSTR)szRecipAccount);
- lstrcpy (pDLInfo->szHeader, (LPSTR)szHeaderInfo);
- GetLocalTempFileName (pDLInfo->szTmpFile);
- if (FALSE == CopyFile (szTmpPath, pDLInfo->szTmpFile, FALSE))
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteSendMsgToAccountA: Failed to create duplicate tmp file for DL delivery", lResult);
- goto ErrorExit;
- }
-
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- g_IOInfo.Action = IO_GET_DL_PROPERTIES;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.phLastError = &lResult;
- g_IOInfo.pDLInfo = &(pDLInfo->DLInfo);
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- if (lResult)
- {
- goto ErrorExit;
- }
- DWORD dwThreadID;
- HANDLE hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)DistListDeliveryThread,
- (LPVOID)pDLInfo,
- CREATE_SUSPENDED,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("RemoteSendMsgToAccountA: Server DL delivery thread spawned. ID: %X", dwThreadID);
- SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
-
- ResumeThread (hThread);
- CloseHandle (hThread);
- pDLInfo = NULL; // The thread will free this memory
- }
- else
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteSendMsgToAccountA: Failed to create Server DL delivery thread", lResult);
- }
- }
- else
- {
- TraceMessage ("RemoteSendMsgToAccountA: This type has not been implemented yet");
- lResult = HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME);
- }
- }
- ErrorExit:
- if (lResult)
- {
- if (pDLInfo)
- {
- DeleteFile (pDLInfo->szTmpFile);
- HeapFree (ghHeap, 0, pDLInfo);
- }
- if (pInfo)
- {
- DeleteFile (pInfo->szTmpFile);
- HeapFree (ghHeap, 0, pInfo);
- }
- }
- if (hFile)
- {
- CloseHandle (hFile);
- }
- if (hWaitEvent)
- {
- CloseHandle (hWaitEvent);
- }
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteFinishUpload()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteFinishUpload (unsigned char * szCookie)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- TCHAR szTmpPath[_MAX_PATH];
- if (!GetTempPath (_MAX_PATH, szTmpPath))
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteFinishUpload: Failed to get temp path", lResult);
- lResult = lResult;
- }
- else
- {
- lstrcat (szTmpPath, (LPSTR)szCookie);
- DeleteFile (szTmpPath);
- }
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteOpenHeaderDownloadPipeA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteOpenHeaderDownloadPipeA (unsigned char * szMailbox, long * pPipeNumber)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- DWORD dwMailboxID;
- if (S_OK != GlobalObjectMap.FindObjFromName (SERVER_USER_MAILBOX, (LPSTR)szMailbox, &dwMailboxID))
- {
- TraceMessage ("RemoteOpenHeaderDownloadPipeA: Invalid user mailbox");
- return HRESULT_FROM_WIN32(ERROR_NO_SUCH_USER);
- }
-
- *pPipeNumber = GetNextPipeID();
-
- TCHAR szBuffer[_MAX_PATH];
- lResult = GetLocalTempFileName (szBuffer);
- if (lResult)
- {
- return lResult;
- }
- HANDLE hFile = CreateFile (szBuffer,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenHeaderDownloadPipeA: Failed to temp file", lResult);
- return lResult;
- }
-
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
- // Initialize the new security descriptor.
- InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
-
- // Add a NULL descriptor ACL to the security descriptor.
- SetSecurityDescriptorDacl (&sd, TRUE, (PACL)NULL, FALSE);
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = TRUE;
-
- wsprintf (szBuffer, SERVER_PIPE_NAME_FORMAT, *pPipeNumber);
- HANDLE hPipe = CreateNamedPipe (szBuffer,
- PIPE_ACCESS_OUTBOUND,
- PIPE_WAIT | PIPE_READMODE_BYTE | PIPE_TYPE_BYTE,
- 1,
- IO_BUFFERSIZE,
- IO_BUFFERSIZE,
- 0,
- &sa);
- if (INVALID_HANDLE_VALUE == hPipe || ERROR_INVALID_PARAMETER == (DWORD)hPipe)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenHeaderDownloadPipeA: Failed to create pipe", lResult);
- }
- else
- {
- PTHREAD_PROC_INFO pInfo = (PTHREAD_PROC_INFO)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(THREAD_PROC_INFO));
- if (pInfo)
- {
- lstrcpy (pInfo->szMailbox, (LPSTR)szMailbox);
- pInfo->hPipe = hPipe;
- pInfo->hTmpFile = hFile;
- DWORD dwThreadID;
- HANDLE hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)HeaderDLPipeThread,
- (LPVOID)pInfo,
- 0,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("RemoteOpenHeaderDownloadPipeA: Header download thread spawned. ID: %X", dwThreadID);
- CloseHandle (hThread);
- }
- else
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenHeaderDownloadPipeA: Failed to create pipe thread", lResult);
- }
- }
- else
- {
- TraceMessage ("RemoteOpenHeaderDownloadPipeA: Failed to allocate info structure");
- lResult = E_OUTOFMEMORY;
- }
- }
- if (lResult)
- {
- CloseHandle (hPipe);
- CloseHandle (hFile);
- }
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteOpenMsgDownloadPipeA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteOpenMsgDownloadPipeA (unsigned char * szMailbox,
- unsigned long * pPipeNumber)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- DWORD dwMailboxID;
- if (S_OK != GlobalObjectMap.FindObjFromName (SERVER_USER_MAILBOX, (LPSTR)szMailbox, &dwMailboxID))
- {
- TraceMessage ("RemoteOpenMsgDownloadPipeA: Invalid user mailbox");
- return HRESULT_FROM_WIN32(ERROR_NO_SUCH_USER);
- }
-
- PTHREAD_PROC_INFO pInfo = (PTHREAD_PROC_INFO)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(THREAD_PROC_INFO));
- if (!pInfo)
- {
- TraceMessage ("RemoteOpenMsgDownloadPipeA: Failed to allocate info structure");
- return E_OUTOFMEMORY;
- }
- lstrcpy (pInfo->szMailbox, (LPSTR)szMailbox);
-
- *pPipeNumber = GetNextPipeID();
-
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
- // Initialize the new security descriptor.
- InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
-
- // Add a NULL descriptor ACL to the security descriptor.
- SetSecurityDescriptorDacl (&sd, TRUE, (PACL)NULL, FALSE);
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = TRUE;
-
- TCHAR szPipeName[64];
- wsprintf (szPipeName, SERVER_PIPE_NAME_FORMAT, *pPipeNumber);
- pInfo->hPipe = CreateNamedPipe (szPipeName,
- PIPE_ACCESS_DUPLEX,
- PIPE_WAIT | PIPE_READMODE_BYTE | PIPE_TYPE_BYTE,
- 1,
- IO_BUFFERSIZE,
- IO_BUFFERSIZE,
- 0,
- &sa);
- if (INVALID_HANDLE_VALUE == pInfo->hPipe || ERROR_INVALID_PARAMETER == (DWORD)pInfo->hPipe)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgDownloadPipeA: Failed to create pipe", lResult);
- }
- else
- {
- DWORD dwThreadID;
- HANDLE hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)MsgDownloadThread,
- (LPVOID)pInfo,
- 0,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("RemoteOpenMsgDownloadPipeA: Header download thread spawned. ID: %X", dwThreadID);
- CloseHandle (hThread);
- }
- else
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgDownloadPipeA: Failed create doanload thread", lResult);
- }
- }
-
- if (lResult)
- {
- if (FACILITY_NULL == HRESULT_FACILITY(lResult))
- {
- lResult = HRESULT_FROM_WIN32 (lResult);
- }
- HeapFree (ghHeap, 0, pInfo);
- }
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // MsgUploadPipeThread()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- HRESULT WINAPI MsgUploadPipeThread (PTHREAD_PROC_INFO pInfo)
- {
- BYTE abBuffer[IO_BUFFERSIZE];
- DWORD dwBytesWrite, dwBytesRead = 0;
-
- ConnectNamedPipe (pInfo->hPipe, NULL);
- HRESULT hResult = S_OK;
- do
- {
- // Wait until the client writes to the pipe
- if (!ReadFile (pInfo->hPipe, abBuffer, IO_BUFFERSIZE, &dwBytesRead, NULL))
- {
- // There was an error and we can't continue
- hResult = HRESULT_FROM_WIN32(GetLastError());
- if (hResult != HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE))
- {
- TraceResult ("MsgUploadPipeThread: Failed to read from the msg upload pipe", hResult);
- }
- else
- {
- hResult = 0;
- }
- }
- if (dwBytesRead && !hResult)
- {
- if (!WriteFile (pInfo->hTmpFile, abBuffer, dwBytesRead, &dwBytesWrite, NULL))
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("MsgUploadPipeThread: Failed to write to the local tmp file", hResult);
- }
- }
- } while (dwBytesRead && !hResult);
-
- TraceResult ("MsgUploadPipeThread", hResult);
- CloseHandle (pInfo->hTmpFile);
- CloseHandle (pInfo->hPipe);
- if (hResult)
- {
- DeleteFile (pInfo->szTmpFile);
- }
- HeapFree (ghHeap, 0, pInfo);
- return hResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // HeaderDLPipeThread()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- HRESULT WINAPI HeaderDLPipeThread (PTHREAD_PROC_INFO pInfo)
- {
- BYTE abBuffer[IO_BUFFERSIZE];
- DWORD dwBytesRead, dwBytesWrite;
- HRESULT hResult;
- HANDLE hWaitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!hWaitEvent)
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("HeaderDLPipeThread: Failed to create event for I/O thread", hResult);
- goto Error;
- }
-
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, pInfo->szMailbox);
- g_IOInfo.Action = IO_COPY_HEADERS_TO_FILE;
- g_IOInfo.hTmpFile = pInfo->hTmpFile;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.phLastError = &hResult;
- LeaveCriticalSection (&g_csIOInfo);
-
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- CloseHandle (hWaitEvent);
- if (hResult)
- {
- goto Error;
- }
-
- // Wait until the client connects to the pipe
- ConnectNamedPipe (pInfo->hPipe, NULL);
-
- do
- {
- if (!ReadFile (pInfo->hTmpFile, abBuffer, IO_BUFFERSIZE, &dwBytesRead, NULL))
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("HeaderDLPipeThread: Failed to read the tmp file", hResult);
- }
- if (dwBytesRead && !hResult)
- {
- if (!WriteFile (pInfo->hPipe, abBuffer, dwBytesRead, &dwBytesWrite, NULL))
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("HeaderDLPipeThread: Failed to write to the pipe", hResult);
- }
- }
- } while (dwBytesRead && !hResult);
-
- Error:
- CloseHandle (pInfo->hTmpFile);
- CloseHandle (pInfo->hPipe);
- HeapFree (ghHeap, 0, pInfo);
- return hResult;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // MsgDownloadThread()
- //
- // Parameters
- // pInfo pointer to a THREAD_PROC_INFO containing the handle to
- // the open pipe for data transmission to the remote XP
- //
- // Purpose
- // This is the worker thread that is spawned when a request to
- // messages arrives from the remote XP via RemoteOpenMsgDownloadPipe.
- // Once the pipe has been opened the remote XP sends command messages
- // on the pipe to request data from the server. These command messages
- // are of 3 types: MSG_MOVE, MSG_DOWNLOAD, and MSG_DELETE. The command
- // messages have a msg ID that tells the requested operation. When this
- // thread is started, it creates an event object for synchronization
- // with the storage thread that accesses the message database then
- // immediately blocks waiting for the XP to connect to the pipe. We
- // unblock and start reading command requests. Each mail message we
- // process goes through the following cycle:
- //
- // 1. read the command message, this contains the operation
- // requested by the XP and the mail message's entry ID
- //
- // 2. if the command is to HANG UP, quit, otherwise:
- //
- // look up the entry ID of the mail message in the storage.
- // if unsuccessful, send a NAK message back to the XP
- //
- // if the request is to DELETE, delete the message and if
- // successful send an ACK message back to the XP, otherwise
- // send a NAK message back, then start on the next request
- //
- // if the request is to MOVE or DOWNLOAD, get the mail message's
- // size, stuff it in an ACK message and write it to the XP.then
- // stream the mail message over the pipe
- //
- // 3. read the next command
- //
- // We treat write errors to the pipe as fatal and disconnect.
- //
- // Return Value
- //
- HRESULT WINAPI MsgDownloadThread(PTHREAD_PROC_INFO pInfo)
- {
- MSG_HDR MsgHdr;
- HANDLE hTmpFile;
- DWORD dwBytesRead, dwBytesWritten;
- HRESULT hResult = S_OK;
- HANDLE hResumeEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- if (!hResumeEvt)
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("MsgDownloadThread: Failed to create event", hResult);
- goto Quit;
- }
-
- // block until XP connects to us
- ConnectNamedPipe (pInfo->hPipe, NULL);
-
- while (TRUE)
- {
- if (!ReadFile(pInfo -> hPipe, &MsgHdr, sizeof(MSG_HDR), &dwBytesRead, NULL))
- break; // Out of the WHILE() loop
-
- ASSERT (dwBytesRead == sizeof(MSG_HDR));
-
- switch (MsgHdr.ulMID)
- {
- case MSG_MOVE: // Fall through
- case MSG_DOWNLOAD:
-
- // tell IO thread to open msg's container, write it
- // to a temp file and return us its size and handle
-
- hTmpFile = OpenMessage(hResumeEvt,
- pInfo->szMailbox,
- MsgHdr.Info.EID,
- MsgHdr.ulMID,
- &MsgHdr.Info.
- ulMsgLen);
- if (!hTmpFile)
- {
- MsgHdr.ulMID = OP_FAILED; // send a NAK back to XP
- MsgHdr.Info.ulMsgLen = 0;
- if (!WriteFile(pInfo->hPipe, &MsgHdr, sizeof(MSG_HDR), &dwBytesWritten, NULL))
- {
- goto Quit;
- }
- }
- else
- {
- MsgHdr.ulMID = OP_STARTED; // send an ACK to XP
- // Bail on any write errors, the connection is down
- if (!WriteFile(pInfo->hPipe, &MsgHdr, sizeof(MSG_HDR), &dwBytesWritten, NULL))
- {
- goto Quit;
- }
-
- // set seek pointer to beginning of temp file
- if ((DWORD)-1 == SetFilePointer(hTmpFile, 0, NULL, FILE_BEGIN))
- break;
-
- if (NO_ERROR != FileCopy(pInfo -> hPipe, hTmpFile, MsgHdr.Info.ulMsgLen))
- goto Quit;
-
- }
- break;
-
- case MSG_DELETE:
- // tell storage thread to delete msg's substorage
- MsgHdr.ulMID = (DeleteMessage (hResumeEvt, pInfo->szMailbox, MsgHdr.Info.EID) ? OP_COMPLETE : OP_FAILED);
- MsgHdr.Info.ulMsgLen = 0;
-
- // send ACK/NAK to XP
- if (!WriteFile (pInfo->hPipe, &MsgHdr, sizeof(MSG_HDR), &dwBytesWritten, NULL))
- {
- goto Quit;
- }
- break;
-
- case GOODBYE: // HANG UP
- goto Quit;
-
- default :
- // don't attempt to resynchronize
- goto Quit;
- }
- }
-
- Quit:
- CloseHandle (pInfo->hPipe);
- CloseHandle (hResumeEvt);
- HeapFree (ghHeap, 0, pInfo);
- return hResult;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // DeleteMessage()
- //
- // Parameters
- // hResumeEvt handle to event object for signaling completion
- // of storage operation
- // szMailBox Name of mailbox for the mail msg we're handling
- // pEID entry ID of msg we're handling
- // Purpose
- // Sends a DELETE request to the storage thread.The request, along
- // with the message's EID, and the mailbox name where the message
- // resides are passed to the storage thread in g_IOInfo. We then block
- // on an event from the storage thread signaling completetion of the
- // requested operations. The storage finds the mail message and
- // deletes it.
- //
- // Return Value
- // TRUE on success,FALSE otherwise
- //
- BOOL WINAPI DeleteMessage(HANDLE hResumeEvt, LPTSTR pszMailBox, LPBYTE pEID)
- {
- HRESULT hResult = S_OK;
- // In Windows NT 3.5 OLE storages can only be accessed by a single thread, so use
- // this global data struct to pass data to the storage thread
- EnterCriticalSection (&g_csIOInfo);
- SetEvent(g_IOInfo.hResumeEvent);
- g_IOInfo.Action = IO_DELETE_MSG_IN_MAILBOX;
- g_IOInfo.hActionCompleted = hResumeEvt;
- g_IOInfo.phLastError = &hResult;
- g_IOInfo.dwObjID = (DWORD)atol((LPCSTR) &pEID[4]);
- lstrcpy (g_IOInfo.szObject, pszMailBox);
- LeaveCriticalSection (&g_csIOInfo);
-
- // Block until the storage thread finishes
- WaitForSingleObject(hResumeEvt, GENERAL_TIME_OUT);
- return (S_OK == hResult ? TRUE : FALSE);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // OpenMessage()
- //
- // Parameters
- // hResumeEvt handle to event object for signaling completion
- // of storage operation
- // pszMailBox name of mailbox for the mail msg we're handling
- // pEID entry ID of msg we're handling
- // ulCmd operation to perform on the message
- // pulMsgLen to pass back the size of the data stream
- // Purpose
- // Create a temporary file to hold the mail message, then send
- // a request for the operation passed in ulCmd to the storage
- // thread.The request, along with the message's EID, the mailbox
- // name where the message resides, and the handle to the tempfile
- // are passed to the storage thread in g_IOInfo. We then block on
- // an event from the storage thread signaling completetion of the
- // requested operations. The storage finds the mail message and
- // copies it into the tempfile passing back the size in pulMsgLen.
- //
- // Return Value
- // Handle of temp file on success, NULL otherwise
- //
- HANDLE WINAPI OpenMessage(HANDLE hResumeEvt,
- LPTSTR pszMailBox,
- LPBYTE pEID,
- ULONG ulCmd,
- ULONG * pulMsgLen)
- {
- HANDLE hTempFile = NULL;
- HRESULT hResult;
- TCHAR szTempFile[MAX_PATH];
- ACTION Action;
- // creates a unique tempfile name
- if (GetLocalTempFileName (szTempFile))
- {
- return NULL;
- }
-
- switch (ulCmd)
- {
- case MSG_DOWNLOAD :
- Action = IO_COPY_MSG_TO_FILE;
- break;
-
- case MSG_MOVE :
- Action = IO_MOVE_MSG_TO_FILE;
- break;
-
- default :
- TraceMessage ("OpenMessage: Invalid command received");
- ASSERT (FALSE);
- return NULL;
- }
-
- // create tempfile to hold message
- if (! (hTempFile = CreateFile(szTempFile,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
- NULL)))
- return NULL;
-
- // OLE storages can only be accessed by a single thread, so use
- // this global data struct to pass data to the storage thread
-
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- g_IOInfo.Action = Action; // requested operation
- g_IOInfo.hActionCompleted = hResumeEvt; // signal us on this event
- g_IOInfo.phLastError = &hResult;
- g_IOInfo.dwObjID = (DWORD) atol((const char *) &pEID[4]);
- g_IOInfo.hTmpFile = hTempFile; // storage thread writes msg here
- g_IOInfo.pdwData = pulMsgLen; // storage thread writes length here
- lstrcpy (g_IOInfo.szObject, pszMailBox);
- LeaveCriticalSection (&g_csIOInfo);
-
- // block until storage thread finishes
- WaitForSingleObject(hResumeEvt, GENERAL_TIME_OUT);
- return (hResult ? NULL : hTempFile);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // DistListDeliveryThread()
- //
- // Parameters
- //
- // Purpose
- // This function is RECURSIVE
- //
- // Return Value
- //
- DWORD WINAPI DistListDeliveryThread (PDL_DELIVERY_PROC_INFO pDLInfo)
- {
- DLM_LIST_A * pNode, *pSubNode;
- DL_DELIVERY_PROC_INFO SubDLInfo = { 0 };
- DWORD j, dwResult = S_OK;
- HRESULT hResult;
- HANDLE hWaitEvent, hFile;
- ObjectDelivered (pDLInfo, pDLInfo->DLInfo.szDLAlias);
- if (NULL == pDLInfo->hFile)
- {
- hFile = CreateFile (pDLInfo->szTmpFile,
- GENERIC_READ,
- 0,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- {
- dwResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("DistListDeliveryThread: Failed to open the temp file", dwResult);
- goto ErrorExit;
- }
- pDLInfo->hFile = hFile;
- }
- else
- {
- hFile = pDLInfo->hFile;
- }
- if (NULL == pDLInfo->hWaitEvent)
- {
- hWaitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!hWaitEvent)
- {
- TraceResult ("DistListDeliveryThread: Failed to create event for I/O thread", HRESULT_FROM_WIN32(GetLastError()));
- }
- pDLInfo->hWaitEvent = hWaitEvent;
- }
- else
- {
- hWaitEvent = pDLInfo->hWaitEvent;
- }
- // Process the USER mailboxes first
- pNode = (DLM_LIST_A *)pDLInfo->DLInfo.pMembers;
- while (pNode)
- {
- if (SERVER_USER_MAILBOX != (WINDS_AB_OBJTYPE)pNode->Info.dwMemberType)
- {
- continue;
- }
- SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, (LPSTR)pNode->Info.szMemberAlias);
- lstrcpy (g_IOInfo.szHeader, pDLInfo->szHeader);
- g_IOInfo.Action = IO_COPY_MSG_FROM_FILE;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.hTmpFile = hFile;
- g_IOInfo.fCloseHandle = FALSE;
- g_IOInfo.phLastError = &hResult;
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
-
- // The message was successfully delivered to the recipient, so add it to the "DELIVERED" list
- if (S_OK == hResult)
- {
- ObjectDelivered (pDLInfo, (LPSTR)pNode->Info.szMemberAlias);
- }
- pNode = pNode->pNext;
- }
- lstrcpy (SubDLInfo.szHeader, pDLInfo->szHeader);
- SubDLInfo.hFile = hFile;
- SubDLInfo.hWaitEvent = hWaitEvent;
-
- // Process the Distribution lists second
- pNode = (DLM_LIST_A *)pDLInfo->DLInfo.pMembers;
- while (pNode)
- {
- if (SERVER_DISTRIBUTION_LIST != (WINDS_AB_OBJTYPE)pNode->Info.dwMemberType)
- {
- continue;
- }
- for (j=0; j<pDLInfo->dwAliasDelivered; j++)
- {
- // If the message has already been delivered to this sub DL, skip it
- if (0 == lstrcmp ((LPSTR)pNode->Info.szMemberAlias, pDLInfo->ppszAliasList[j]))
- {
- continue;
- }
- }
-
- lstrcpy (SubDLInfo.DLInfo.szDLAlias, (LPSTR)pNode->Info.szMemberAlias);
- SubDLInfo.fDeleteInfoStruct = FALSE;
- SubDLInfo.DLInfo.pMembers = NULL;
- SubDLInfo.dwAliasDelivered = pDLInfo->dwAliasDelivered;
- SubDLInfo.ppszAliasList = pDLInfo->ppszAliasList;
-
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- g_IOInfo.Action = IO_GET_DL_PROPERTIES;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.phLastError = &hResult;
- g_IOInfo.pDLInfo = &(SubDLInfo.DLInfo);
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- if (hResult)
- {
- TraceResult ("DistListDeliveryThread: Could not get DL properties", hResult);
- continue;
- }
-
- pSubNode = (DLM_LIST_A *)SubDLInfo.DLInfo.pMembers;
- while (pSubNode)
- {
- for (j=0; j<pDLInfo->dwAliasDelivered; j++)
- {
- // If the message has already been delivered to a member of the Sub DL
- // mark the entry in the sub DL so that it won't deliver to that recipient.
- if (0 == lstrcmp ((LPSTR)pSubNode->Info.szMemberAlias, pDLInfo->ppszAliasList[j]))
- {
- pSubNode->Info.dwMemberType = (DWORD)UNDEFINED_OBJECT_TYPE;
- }
- }
- pSubNode = pSubNode->pNext;
- }
- // Deliver to the members of the sub-distribution list
- hResult = DistListDeliveryThread (&SubDLInfo);
- // Remember how many recipients were handled in this sub DL
- pDLInfo->dwAliasDelivered = SubDLInfo.dwAliasDelivered;
- pDLInfo->ppszAliasList = SubDLInfo.ppszAliasList;
- if (SubDLInfo.DLInfo.pMembers)
- {
- HeapFree (ghHeap, 0, SubDLInfo.DLInfo.pMembers);
- }
- pNode = pNode->pNext;
- }
-
- ErrorExit:
- if (pDLInfo->fDeleteInfoStruct)
- {
- CloseHandle (pDLInfo->hWaitEvent);
- CloseHandle (pDLInfo->hFile);
- DeleteFile (pDLInfo->szTmpFile);
- if (pDLInfo->DLInfo.pMembers)
- {
- HeapFree (ghHeap, 0, pDLInfo->DLInfo.pMembers);
- }
- if (pDLInfo->ppszAliasList)
- {
- for (j=0; j<pDLInfo->dwAliasDelivered; j++)
- {
- HeapFree (ghHeap, 0, pDLInfo->ppszAliasList[j]);
- }
- HeapFree (ghHeap, 0, pDLInfo->ppszAliasList);
- }
- HeapFree (ghHeap, 0, pDLInfo);
- }
- return dwResult;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // ObjectDelivered()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- HRESULT WINAPI ObjectDelivered (PDL_DELIVERY_PROC_INFO pDLInfo, LPTSTR szObject)
- {
- DWORD dwIndex = pDLInfo->dwAliasDelivered;
- if (NULL == pDLInfo->ppszAliasList)
- {
- ASSERT (0 == pDLInfo->dwAliasDelivered);
- pDLInfo->ppszAliasList = (LPTSTR *)HeapAlloc (ghHeap, 0, sizeof(LPTSTR));
- if (NULL == pDLInfo->ppszAliasList)
- {
- TraceMessage ("ObjectDelivered: Failed to allocate Delivered Alias List");
- return E_OUTOFMEMORY;
- }
- }
- else
- {
- pDLInfo->ppszAliasList = (LPTSTR *)HeapReAlloc (ghHeap,
- 0,
- pDLInfo->ppszAliasList,
- sizeof(LPTSTR) * (pDLInfo->dwAliasDelivered + 1));
- if (NULL == pDLInfo->ppszAliasList[dwIndex])
- {
- TraceMessage ("ObjectDelivered: Failed to re-allocate Delivered Alias List");
- return E_OUTOFMEMORY;
- }
- }
-
- pDLInfo->ppszAliasList[dwIndex] = (LPTSTR)HeapAlloc (ghHeap, 0, (sizeof (TCHAR)*(lstrlen(szObject)+1)));
- if (NULL == pDLInfo->ppszAliasList[dwIndex])
- {
- TraceMessage ("ObjectDelivered: Failed to allocate object alias string");
- return E_OUTOFMEMORY;
- }
- lstrcpy (pDLInfo->ppszAliasList[dwIndex], szObject);
- pDLInfo->dwAliasDelivered++;
- return S_OK;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteCheckNewMailA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteCheckNewMailA (unsigned char * szMailbox, unsigned long * pulPending)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- HANDLE hWaitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!hWaitEvent)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteCheckNewMailA: Failed to create event for I/O thread", lResult);
- return lResult;
- }
- *pulPending = 0;
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, (LPSTR)szMailbox);
- g_IOInfo.Action = IO_CHECK_PENDING_MESSAGES;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.phLastError = &lResult;
- g_IOInfo.pdwData = pulPending;
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- CloseHandle (hWaitEvent);
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteOpenOneMsgDownloadPipeA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteOpenOneMsgDownloadPipeA (unsigned char * szMailbox,
- long * pPipeNumber)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- TCHAR szTmpFile[_MAX_PATH], szPipeName[64];
- lResult = GetLocalTempFileName (szTmpFile);
- if (lResult)
- {
- return lResult;
- }
-
- PTHREAD_PROC_INFO pInfo = (PTHREAD_PROC_INFO)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(THREAD_PROC_INFO));
- if (NULL == pInfo)
- {
- TraceMessage ("RemoteOpenOneMsgDownloadPipeA: Failed to allocate info structure");
- return E_OUTOFMEMORY;
- }
- DWORD dwThreadID, dwMsgID;
- HANDLE hThread, hWaitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!hWaitEvent)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenOneMsgDownloadPipeA: Failed to create event for I/O thread", lResult);
- goto ErrorExit;
- }
-
- pInfo->hTmpFile = CreateFile (szTmpFile,
- GENERIC_WRITE | GENERIC_READ,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
- if (INVALID_HANDLE_VALUE == pInfo->hTmpFile)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenOneMsgDownloadPipeA: Failed to create the temp file", lResult);
- goto ErrorExit;
- }
-
- *pPipeNumber = GetNextPipeID();
-
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
- // Initialize the new security descriptor.
- InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
-
- // Add a NULL descriptor ACL to the security descriptor.
- SetSecurityDescriptorDacl (&sd, TRUE, (PACL)NULL, FALSE);
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = TRUE;
-
- wsprintf (szPipeName, SERVER_PIPE_NAME_FORMAT, *pPipeNumber);
- pInfo->hPipe = CreateNamedPipe (szPipeName,
- PIPE_ACCESS_OUTBOUND,
- PIPE_WAIT | PIPE_READMODE_BYTE | PIPE_TYPE_BYTE,
- 1,
- IO_BUFFERSIZE,
- IO_BUFFERSIZE,
- 0,
- &sa);
- if (INVALID_HANDLE_VALUE == pInfo->hPipe || ERROR_INVALID_PARAMETER == (DWORD)pInfo->hPipe)
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenMsgDownloadPipeA: Failed to create pipe", lResult);
- goto ErrorExit;
- }
-
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, (LPSTR)szMailbox);
- g_IOInfo.Action = IO_MOVE_NEXT_MSG_TO_FILE;
- g_IOInfo.hActionCompleted = hWaitEvent;
- g_IOInfo.hTmpFile = pInfo->hTmpFile;
- g_IOInfo.pdwData = &dwMsgID;
- g_IOInfo.phLastError = &lResult;
- LeaveCriticalSection (&g_csIOInfo);
- WaitForSingleObject (hWaitEvent, GENERAL_TIME_OUT);
- if (lResult)
- {
- goto ErrorExit;
- }
-
- hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)OneMsgDownloadPipeThread,
- (LPVOID)pInfo,
- 0,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("RemoteOpenOneMsgDownloadPipeA: Message Download thread spawned. ID: %X", dwThreadID);
- CloseHandle (hThread);
- pInfo = NULL; // The thread will free this memory
- EnterCriticalSection (&g_csIOInfo);
- SetEvent (g_IOInfo.hResumeEvent);
- lstrcpy (g_IOInfo.szObject, (LPSTR)szMailbox);
- g_IOInfo.Action = IO_DELETE_MSG_IN_MAILBOX;
- g_IOInfo.hActionCompleted = NULL;
- g_IOInfo.dwObjID = dwMsgID;
- g_IOInfo.phLastError = NULL;
- LeaveCriticalSection (&g_csIOInfo);
- }
- else
- {
- lResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("RemoteOpenOneMsgDownloadPipeA: Failed to create pipe thread", lResult);
- }
-
- ErrorExit:
- if (pInfo)
- {
- if (pInfo->hTmpFile)
- {
- CloseHandle (pInfo->hTmpFile);
- }
- if (pInfo->hPipe)
- {
- CloseHandle (pInfo->hPipe);
- }
- HeapFree (ghHeap, 0, pInfo);
- }
- if (hWaitEvent)
- {
- CloseHandle (hWaitEvent);
- }
- #ifdef _DEBUG
- if (lResult && S_FALSE != lResult)
- {
- TraceResult ("RemoteOpenOneMsgDownloadPipeA", lResult);
- }
- #endif // _DEBUG
- return lResult;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // OneMsgDownloadPipeThread()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- HRESULT WINAPI OneMsgDownloadPipeThread (PTHREAD_PROC_INFO pInfo)
- {
- DWORD dwBytesRead, dwBytesWritten;
- BYTE abBuffer[IO_BUFFERSIZE];
- HRESULT hResult = S_OK;
-
- SetFilePointer (pInfo->hTmpFile, 0, NULL, FILE_BEGIN);
-
- ConnectNamedPipe (pInfo->hPipe, NULL);
-
- do
- {
- if (!ReadFile (pInfo->hTmpFile, abBuffer, IO_BUFFERSIZE, &dwBytesRead, NULL))
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("OneMsgDownloadPipeThread: Failed to read the tmp file", hResult);
- }
- if (dwBytesRead && !hResult)
- {
- if (!WriteFile (pInfo->hPipe, abBuffer, dwBytesRead, &dwBytesWritten, NULL))
- {
- hResult = HRESULT_FROM_WIN32(GetLastError());
- TraceResult ("OneMsgDownloadPipeThread: Failed to write to the pipe", hResult);
- }
- }
- } while (dwBytesRead && !hResult);
-
- TraceResult ("OneMsgDownloadPipeThread", hResult);
- CloseHandle (pInfo->hPipe);
- CloseHandle (pInfo->hTmpFile);
- HeapFree (ghHeap, 0, pInfo);
- return hResult;
- }
-
- // End of file for RXPRPC.CPP
-