static NTSTATUS ExpandCommands( PKQUEUE_COMMANDS pCommands ) { NTSTATUS status = STATUS_SUCCESS; ULONG ulNewCapacity = 0; struct kevent* pNewCommands = NULL; if (pCommands->ulCommandMax + COMMANDS_PER_FD > pCommands->ulCommandCapacity) { ulNewCapacity = pCommands->ulCommandCapacity; if (ulNewCapacity == 0) { ulNewCapacity = 8; } while (pCommands->ulCommandMax > ulNewCapacity) { ulNewCapacity *= 2; } pNewCommands = LwRtlMemoryRealloc( pCommands->pCommands, sizeof(*pNewCommands) * ulNewCapacity); if (!pNewCommands) { status = STATUS_INSUFFICIENT_RESOURCES; GOTO_ERROR_ON_STATUS(status); } pCommands->ulCommandCapacity = ulNewCapacity; pCommands->pCommands = pNewCommands; } pCommands->ulCommandMax += COMMANDS_PER_FD; error: return status; }
LW_NTSTATUS LwIoReallocMemory( LW_PVOID pMemory, size_t Size, LW_PVOID * ppNewMemory ) { PVOID pNewMemory = LwRtlMemoryRealloc(pMemory, Size); if (!pNewMemory) { *ppNewMemory = NULL; return STATUS_INSUFFICIENT_RESOURCES; } else { *ppNewMemory = pNewMemory; return STATUS_SUCCESS; } }
static DWORD LWNetNbResolveNameUdp( PSTR pszHostName, PSTR winsServer, UINT8 queryType, OUT struct in_addr **retAddrs, OUT PDWORD retAddrsLen) { DWORD dwError = 0; UINT16 transactionId = 0; UINT8 *NetBiosQuery = NULL; DWORD NetBiosQueryLen = 0; struct sockaddr_in dgAddr; struct timespec cvTimeout = {0}; struct timeval tp = {0}; struct in_addr *resAddrs = NULL; struct in_addr *tmpResAddrs = NULL; int sts = 0; DWORD i = 0; DWORD resAddrsLen = 0; DWORD resAddrsAllocLen = 128; DWORD commType = 0; BOOLEAN bLocked = FALSE; dwError = LWNetAllocateMemory( LWNB_NETBIOS_UDP_MAX, (PVOID*) &NetBiosQuery); BAIL_ON_LWNET_ERROR(dwError); memset(&dgAddr, 0, sizeof(dgAddr)); dgAddr.sin_family = AF_INET; dgAddr.sin_port = htons(137); if (winsServer && *winsServer) { sts = inet_aton(winsServer, &dgAddr.sin_addr); if (sts == -1) { dwError = LwErrnoToWin32Error(ERROR_INCORRECT_ADDRESS); BAIL_ON_LWNET_ERROR(dwError); } commType = LWNB_QUERY_WINS; dwError = LWNetNbConstructNameQuery( pszHostName, commType, queryType, &transactionId, NetBiosQuery, &NetBiosQueryLen); BAIL_ON_LWNET_ERROR(dwError); } else { dgAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); commType = LWNB_QUERY_BROADCAST; dwError = LWNetNbConstructNameQuery( pszHostName, commType, queryType, &transactionId, NetBiosQuery, &NetBiosQueryLen); BAIL_ON_LWNET_ERROR(dwError); } // If this is not enough memory, realloc below fixes that dwError = LWNetAllocateMemory( resAddrsAllocLen * sizeof(struct in_addr), (PVOID*) &resAddrs); BAIL_ON_LWNET_ERROR(dwError); pthread_mutex_lock(&gpNbCtx->mutex); bLocked = TRUE; sts = sendto(gpNbCtx->sock, NetBiosQuery, NetBiosQueryLen, 0, /* flags */ (struct sockaddr *) &dgAddr, sizeof(dgAddr)); if (sts == -1) { dwError = ERROR_NET_WRITE_FAULT; BAIL_ON_LWNET_ERROR(dwError); } do { gettimeofday(&tp, NULL); cvTimeout.tv_sec = tp.tv_sec + gpNbCtx->udpTimeout; cvTimeout.tv_nsec = tp.tv_usec * 1000; do { sts = pthread_cond_timedwait( &gpNbCtx->cv, &gpNbCtx->mutex, &cvTimeout); } while (!gpNbCtx->bNbRepsponse && sts != ETIMEDOUT); if (sts == 0 && gpNbCtx->transactionId == transactionId) { gpNbCtx->bNbRepsponse = FALSE; if ((commType == LWNB_QUERY_WINS && gpNbCtx->respError == 0) || (commType == LWNB_QUERY_BROADCAST)) { if ((gpNbCtx->addrsLen + resAddrsLen) > resAddrsAllocLen) { resAddrsAllocLen = resAddrsAllocLen * 2 + gpNbCtx->addrsLen; tmpResAddrs = LwRtlMemoryRealloc( resAddrs, resAddrsAllocLen); if (!tmpResAddrs) { dwError = ERROR_NOT_ENOUGH_MEMORY; BAIL_ON_LWNET_ERROR(dwError); } resAddrs = tmpResAddrs; tmpResAddrs = NULL; } for (i=0; i<gpNbCtx->addrsLen; i++) { memcpy(&resAddrs[resAddrsLen++], &gpNbCtx->addrs[i], sizeof(struct in_addr)); } } pthread_mutex_lock(&gpNbCtx->mutexAck); gpNbCtx->bAck = TRUE; pthread_mutex_unlock(&gpNbCtx->mutexAck); pthread_cond_signal(&gpNbCtx->cvAck); if (commType == LWNB_QUERY_WINS && gpNbCtx->respError) { // Bail when WINS query fails to resolve the hostname dwError = gpNbCtx->respError; BAIL_ON_LWNET_ERROR(dwError); } } } while (commType == LWNB_QUERY_BROADCAST && sts != ETIMEDOUT); bLocked = FALSE; pthread_mutex_unlock(&gpNbCtx->mutex); if (resAddrsLen == 0) { dwError = ERROR_BAD_NET_NAME; BAIL_ON_LWNET_ERROR(dwError); } *retAddrs = resAddrs; *retAddrsLen = resAddrsLen; cleanup: if (bLocked) { pthread_mutex_unlock(&gpNbCtx->mutex); } LWNET_SAFE_FREE_MEMORY(NetBiosQuery); return dwError; error: LWNET_SAFE_FREE_MEMORY(resAddrs); goto cleanup; }
LW_NTSTATUS LwIoGetPeerAccessToken( IO_FILE_HANDLE File, PACCESS_TOKEN* ppToken ) { NTSTATUS Status = STATUS_SUCCESS; IO_STATUS_BLOCK IoStatus; ULONG ulLength = ACCESS_TOKEN_LENGTH; PBYTE pBuffer = NULL; PBYTE pNewBuffer = NULL; Status = RTL_ALLOCATE(&pBuffer, BYTE, ulLength); BAIL_ON_NT_STATUS(Status); do { Status = LwNtFsControlFile( File, NULL, &IoStatus, IO_FSCTL_SMB_GET_PEER_ACCESS_TOKEN, NULL, 0, pBuffer, ulLength); if (Status == STATUS_BUFFER_TOO_SMALL) { ulLength *= 2; pNewBuffer = LwRtlMemoryRealloc(pBuffer, ulLength); if (!pNewBuffer) { Status = STATUS_INSUFFICIENT_RESOURCES; BAIL_ON_NT_STATUS(Status); } pBuffer = pNewBuffer; } } while (Status == STATUS_BUFFER_TOO_SMALL); BAIL_ON_NT_STATUS(Status); if (IoStatus.BytesTransferred > 0) { Status = RtlSelfRelativeAccessTokenToAccessToken( (PACCESS_TOKEN_SELF_RELATIVE) pBuffer, IoStatus.BytesTransferred, ppToken); BAIL_ON_NT_STATUS(Status); } else { *ppToken = NULL; } cleanup: RTL_FREE(&pBuffer); return Status; error: *ppToken = NULL; goto cleanup; }
LW_NTSTATUS LwIoRdrGetPhysicalPath( IO_FILE_HANDLE File, LW_PWSTR* ppResolved ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus; ULONG length = RESOLVED_PATH_LENGTH; PBYTE pBuffer = NULL; PBYTE pNewBuffer = NULL; PWSTR pResolved = NULL; status = RTL_ALLOCATE(&pBuffer, BYTE, length); GOTO_CLEANUP_ON_STATUS(status); do { status = LwNtDeviceIoControlFile( File, NULL, &ioStatus, RDR_DEVCTL_GET_PHYSICAL_PATH, NULL, 0, pBuffer, length); if (status == STATUS_BUFFER_TOO_SMALL) { length *= 2; pNewBuffer = LwRtlMemoryRealloc(pBuffer, length); if (!pNewBuffer) { status = STATUS_INSUFFICIENT_RESOURCES; GOTO_CLEANUP_ON_STATUS(status); } pBuffer = pNewBuffer; } } while (status == STATUS_BUFFER_TOO_SMALL); GOTO_CLEANUP_ON_STATUS(status); if (ioStatus.BytesTransferred > 0) { status = LW_RTL_ALLOCATE( &pResolved, WCHAR, ioStatus.BytesTransferred + sizeof(WCHAR)); GOTO_CLEANUP_ON_STATUS(status); #ifdef WORDS_BIGENDIAN swab(pBuffer, pResolved, ioStatus.BytesTransferred); #else memcpy(pResolved, pBuffer, ioStatus.BytesTransferred); #endif } cleanup: *ppResolved = pResolved; RTL_FREE(&pBuffer); return status; }