/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32 Kernel Library
- * FILE: lib/kernel32/file/npipe.c
+ * FILE: dll/win32/kernel32/client/file/npipe.c
* PURPOSE: Named Pipe Functions
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
* Ariadne ( ariadne@xs4all.nl)
/* FUNCTIONS ******************************************************************/
+/*
+ * @implemented
+ */
+static
+BOOL
+NpGetUserNamep(HANDLE hNamedPipe,
+ LPWSTR lpUserName,
+ DWORD nMaxUserNameSize)
+{
+ BOOL Ret;
+ HANDLE hToken;
+ HMODULE hAdvapi;
+ NTSTATUS Status;
+ BOOL (WINAPI *pRevertToSelf)(void);
+ BOOL (WINAPI *pGetUserNameW)(LPWSTR lpBuffer, LPDWORD lpnSize);
+ BOOL (WINAPI *pImpersonateNamedPipeClient)(HANDLE hNamedPipe);
+
+ /* Open advapi, we'll funcs from it */
+ hAdvapi = LoadLibraryW(L"advapi32.dll");
+ if (hAdvapi == NULL)
+ {
+ return FALSE;
+ }
+
+ /* Import the three required functions */
+ pRevertToSelf = (BOOL (WINAPI *)(void))GetProcAddress(hAdvapi, "RevertToSelf");
+ pGetUserNameW = (BOOL (WINAPI *)(LPWSTR, LPDWORD))GetProcAddress(hAdvapi, "GetUserNameW");
+ pImpersonateNamedPipeClient = (BOOL (WINAPI *)(HANDLE))GetProcAddress(hAdvapi, "ImpersonateNamedPipeClient");
+ /* If any couldn't be found, fail */
+ if (pRevertToSelf == NULL || pGetUserNameW == NULL || pImpersonateNamedPipeClient == NULL)
+ {
+ FreeLibrary(hAdvapi);
+ return FALSE;
+ }
+
+ /* Now, open the thread token for impersonation */
+ Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_IMPERSONATE, TRUE, &hToken);
+ /* Try to impersonate the pipe client */
+ if (pImpersonateNamedPipeClient(hNamedPipe))
+ {
+ DWORD lpnSize;
+
+ /* It worked, get the user name */
+ lpnSize = nMaxUserNameSize;
+ Ret = pGetUserNameW(lpUserName, &lpnSize);
+ /* Failed to get the thread token? Revert to self */
+ if (!NT_SUCCESS(Status))
+ {
+ pRevertToSelf();
+
+ FreeLibrary(hAdvapi);
+ return Ret;
+ }
+
+ /* Restore the thread token */
+ Status = NtSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,
+ &hToken, sizeof(HANDLE));
+ /* We cannot fail closing the thread token! */
+ if (!CloseHandle(hToken))
+ {
+ ASSERT(FALSE);
+ }
+
+ /* Set last error if it failed */
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ }
+ }
+ else
+ {
+ /* If opening the thread token succeed, close it */
+ if (NT_SUCCESS(Status))
+ {
+ /* We cannot fail closing it! */
+ if (!CloseHandle(hToken))
+ {
+ ASSERT(FALSE);
+ }
+ }
+
+ Ret = FALSE;
+ }
+
+ FreeLibrary(hAdvapi);
+ return Ret;
+}
+
+
/*
* @implemented
*/
if (nDefaultTimeOut)
{
/* Convert the time to NT format */
- DefaultTimeOut.QuadPart = UInt32x32To64(nDefaultTimeOut, -10000);
+ DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000LL;
}
else
{
WaitNamedPipeA(LPCSTR lpNamedPipeName,
DWORD nTimeOut)
{
- BOOL r;
+ BOOL r = FALSE;
UNICODE_STRING NameU;
/* Convert the name to Unicode */
- Basep8BitStringToDynamicUnicodeString(&NameU, lpNamedPipeName);
-
- /* Call the Unicode API */
- r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
+ if (Basep8BitStringToDynamicUnicodeString(&NameU, lpNamedPipeName))
+ {
+ /* Call the Unicode API */
+ r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
- /* Free the Unicode string */
- RtlFreeUnicodeString(&NameU);
+ /* Free the Unicode string */
+ RtlFreeUnicodeString(&NameU);
+ }
/* Return result */
return r;
else
{
/* Convert to NT format */
- WaitPipeInfo->Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
+ WaitPipeInfo->Timeout.QuadPart = nTimeOut * -10000LL;
}
/* In both cases, we do have a timeout */
if (lpCollectDataTimeout)
{
/* Convert it to Quad */
- RemoteSettings.CollectDataTime.QuadPart =
- -(LONGLONG)UInt32x32To64(10000, *lpCollectDataTimeout);
+ RemoteSettings.CollectDataTime.QuadPart = *lpCollectDataTimeout * -10000LL;
}
/* Tell the driver to change them */
*lpMaxCollectionCount = RemoteInfo.MaximumCollectionCount;
}
- if(lpCollectDataTimeout != NULL)
+ if (lpCollectDataTimeout != NULL)
{
- /* FIXME */
- *lpCollectDataTimeout = 0;
+ LARGE_INTEGER CollectDataTime;
+
+ /* Convert time and return it */
+ RemoteInfo.CollectDataTime.QuadPart *= -1;
+ CollectDataTime = RtlExtendedLargeIntegerDivide(RemoteInfo.CollectDataTime, 10000, NULL);
+ /* In case of overflow, just return MAX - 1 */
+ if (CollectDataTime.HighPart != 0)
+ {
+ *lpCollectDataTimeout = -2;
+ }
+ else
+ {
+ *lpCollectDataTimeout = CollectDataTime.LowPart;
+ }
}
}
if (lpUserName != NULL)
{
- /* FIXME - open the thread token, call ImpersonateNamedPipeClient() and
- retreive the user name with GetUserName(), revert the impersonation
- and finally restore the thread token */
+ return NpGetUserNamep(hNamedPipe, lpUserName, nMaxUserNameSize);
}
return TRUE;