⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 npipe.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
        {
            /* 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 + -