HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { int i; if (!lpFileName) return INVALID_HANDLE_VALUE; if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } if (_HandleCreators == NULL) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } ArrayList_Lock(_HandleCreators); for (i=0; i <= ArrayList_Count(_HandleCreators); i++) { HANDLE_CREATOR* creator = ArrayList_GetItem(_HandleCreators, i); if (creator && creator->IsHandled(lpFileName)) { HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); ArrayList_Unlock(_HandleCreators); return newHandle; } } ArrayList_Unlock(_HandleCreators); return INVALID_HANDLE_VALUE; }
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { int i; char* name; int status; HANDLE hNamedPipe; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; if (!lpFileName) return INVALID_HANDLE_VALUE; if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } if (_HandleCreators == NULL) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } EnterCriticalSection(&_HandleCreatorsLock); for (i=0; _HandleCreators[i] != NULL; i++) { HANDLE_CREATOR* creator = (HANDLE_CREATOR*)_HandleCreators[i]; if (creator && creator->IsHandled(lpFileName)) { HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); LeaveCriticalSection(&_HandleCreatorsLock); return newHandle; } } LeaveCriticalSection(&_HandleCreatorsLock); /* TODO: use of a HANDLE_CREATOR for named pipes as well */ if (!IsNamedPipeFileNameA(lpFileName)) return INVALID_HANDLE_VALUE; name = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!name) return INVALID_HANDLE_VALUE; free(name); pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE)); if (!pNamedPipe) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return INVALID_HANDLE_VALUE; } hNamedPipe = (HANDLE) pNamedPipe; WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ); pNamedPipe->name = _strdup(lpFileName); if (!pNamedPipe->name) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->dwOpenMode = 0; pNamedPipe->dwPipeMode = 0; pNamedPipe->nMaxInstances = 0; pNamedPipe->nOutBufferSize = 0; pNamedPipe->nInBufferSize = 0; pNamedPipe->nDefaultTimeOut = 0; pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!pNamedPipe->lpFileName) { free((void *)pNamedPipe->name); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName); if (!pNamedPipe->lpFilePath) { free((void *)pNamedPipe->lpFileName); free((void *)pNamedPipe->name); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0); pNamedPipe->serverfd = -1; pNamedPipe->ServerMode = FALSE; ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); pNamedPipe->ops = &ops; if (status != 0) { close(pNamedPipe->clientfd); free((char*) pNamedPipe->name); free((char*) pNamedPipe->lpFileName); free((char*) pNamedPipe->lpFilePath); free(pNamedPipe); return INVALID_HANDLE_VALUE; } if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) { #if 0 int flags = fcntl(pNamedPipe->clientfd, F_GETFL); if (flags != -1) fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK); #endif } return hNamedPipe; }