📄 npipe.c
字号:
{
/* Convert to NT format */
WaitPipeInfo->Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
}
/* In both cases, we do have a timeout */
WaitPipeInfo->TimeoutSpecified = FALSE;
}
/* Set the length and copy the name */
WaitPipeInfo->NameLength = NewName.Length;
RtlCopyMemory(WaitPipeInfo->Name, NewName.Buffer, NewName.Length);
/* Get rid of the full name */
RtlFreeUnicodeString(&NamedPipeName);
/* Let NPFS know of our request */
Status = NtFsControlFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_PIPE_WAIT,
WaitPipeInfo,
WaitPipeInfoSize,
NULL,
0);
/* Free our pipe info data and close the handle */
RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo);
NtClose(FileHandle);
/* Check the status */
if (!NT_SUCCESS(Status))
{
/* Failure to wait on the pipe */
DPRINT1("Status: %lx\n", Status);
SetLastErrorByStatus (Status);
return FALSE;
}
/* Success */
return TRUE;
}
#else
/*
* @implemented
*/
BOOL STDCALL
WaitNamedPipeW(LPCWSTR lpNamedPipeName,
DWORD nTimeOut)
{
UNICODE_STRING NamedPipeName;
BOOL r;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
HANDLE FileHandle;
IO_STATUS_BLOCK Iosb;
r = RtlDosPathNameToNtPathName_U(lpNamedPipeName,
&NamedPipeName,
NULL,
NULL);
if (!r)
{
return(FALSE);
}
InitializeObjectAttributes(&ObjectAttributes,
&NamedPipeName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
&ObjectAttributes,
&Iosb,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return(FALSE);
}
WaitPipe.Timeout.QuadPart = nTimeOut * -10000LL;
Status = NtFsControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_PIPE_WAIT,
&WaitPipe,
sizeof(WaitPipe),
NULL,
0);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return(FALSE);
}
return(TRUE);
}
#endif
/*
* @implemented
*/
BOOL STDCALL
ConnectNamedPipe(IN HANDLE hNamedPipe,
IN LPOVERLAPPED lpOverlapped)
{
NTSTATUS Status;
if (lpOverlapped != NULL)
{
PVOID ApcContext;
lpOverlapped->Internal = STATUS_PENDING;
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
Status = NtFsControlFile(hNamedPipe,
lpOverlapped->hEvent,
NULL,
ApcContext,
(PIO_STATUS_BLOCK)lpOverlapped,
FSCTL_PIPE_LISTEN,
NULL,
0,
NULL,
0);
/* return FALSE in case of failure and pending operations! */
if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
{
SetLastErrorByStatus(Status);
return FALSE;
}
}
else
{
IO_STATUS_BLOCK Iosb;
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_PIPE_LISTEN,
NULL,
0,
NULL,
0);
/* wait in case operation is pending */
if (Status == STATUS_PENDING)
{
Status = NtWaitForSingleObject(hNamedPipe,
FALSE,
NULL);
if (NT_SUCCESS(Status))
{
Status = Iosb.Status;
}
}
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
}
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
SetNamedPipeHandleState(HANDLE hNamedPipe,
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout)
{
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
/* Check if the Mode is being changed */
if (lpMode)
{
FILE_PIPE_INFORMATION Settings;
/* Set the Completion Mode */
Settings.CompletionMode = (*lpMode & PIPE_NOWAIT) ?
FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
/* Set the Read Mode */
Settings.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ?
FILE_PIPE_MESSAGE_MODE: FILE_PIPE_BYTE_STREAM_MODE;
/* Send the changes to the Driver */
Status = NtSetInformationFile(hNamedPipe,
&Iosb,
&Settings,
sizeof(FILE_PIPE_INFORMATION),
FilePipeInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* Check if the Collection count or Timeout are being changed */
if (lpMaxCollectionCount || lpCollectDataTimeout)
{
FILE_PIPE_REMOTE_INFORMATION RemoteSettings;
/* Setting one without the other would delete it, so we read old one */
if (!lpMaxCollectionCount || !lpCollectDataTimeout)
{
Status = NtQueryInformationFile(hNamedPipe,
&Iosb,
&RemoteSettings,
sizeof(FILE_PIPE_REMOTE_INFORMATION),
FilePipeRemoteInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* Now set the new settings */
RemoteSettings.MaximumCollectionCount = (lpMaxCollectionCount) ?
*lpMaxCollectionCount :
RemoteSettings.MaximumCollectionCount;
if (lpCollectDataTimeout)
{
/* Convert it to Quad */
RemoteSettings.CollectDataTime.QuadPart = -(LONGLONG)
UInt32x32To64(10000,
*lpCollectDataTimeout);
}
/* Tell the driver to change them */
Status = NtSetInformationFile(hNamedPipe,
&Iosb,
&RemoteSettings,
sizeof(FILE_PIPE_REMOTE_INFORMATION),
FilePipeRemoteInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* All done */
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
CallNamedPipeA(LPCSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesRead,
DWORD nTimeOut)
{
PUNICODE_STRING PipeName = &NtCurrentTeb()->StaticUnicodeString;
ANSI_STRING AnsiPipe;
/* Initialize the string as ANSI_STRING and convert to Unicode */
RtlInitAnsiString(&AnsiPipe, (LPSTR)lpNamedPipeName);
RtlAnsiStringToUnicodeString(PipeName, &AnsiPipe, FALSE);
/* Call the Unicode function */
return CallNamedPipeW(PipeName->Buffer,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
nOutBufferSize,
lpBytesRead,
nTimeOut);
}
/*
* @implemented
*/
BOOL
WINAPI
CallNamedPipeW(LPCWSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesRead,
DWORD nTimeOut)
{
HANDLE hPipe;
BOOL bRetry = TRUE;
BOOL bError;
DWORD dwPipeMode;
while (TRUE)
{
/* Try creating it */
hPipe = CreateFileW(lpNamedPipeName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
/* Success, break out */
if (hPipe != INVALID_HANDLE_VALUE) break;
/* Already tried twice, give up */
if (bRetry == FALSE) return FALSE;
/* Wait on it */
WaitNamedPipeW(lpNamedPipeName, nTimeOut);
/* Get ready to try again */
bRetry = FALSE;
}
/* Set the pipe mode */
dwPipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
bError = SetNamedPipeHandleState(hPipe, &dwPipeMode, NULL, NULL);
if (!bError)
{
/* Couldn't change state, fail */
CloseHandle(hPipe);
return FALSE;
}
/* Do the transact */
bError = TransactNamedPipe(hPipe,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
nOutBufferSize,
lpBytesRead,
NULL);
/* Close the handle and return */
CloseHandle(hPipe);
return bError;
}
/*
* @implemented
*/
BOOL
WINAPI
DisconnectNamedPipe(HANDLE hNamedPipe)
{
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
/* Send the FSCTL to the driver */
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_PIPE_DISCONNECT,
NULL,
0,
NULL,
0);
if (Status == STATUS_PENDING)
{
/* Wait on NPFS to finish and get updated status */
Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
if (NT_SUCCESS(Status)) Status = Iosb.Status;
}
/* Check for error */
if (!NT_SUCCESS(Status))
{
/* Fail */
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @unimplemented
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -