/** * @brief Releases a mutex. * @param[in] h the mutex handle. * @return Zero for success, * negative value otherwise. */ int winx_release_mutex(HANDLE h) { NTSTATUS status; DbgCheck1(h,-1); status = NtReleaseMutant(h,NULL); if(!NT_SUCCESS(status)){ strace(status,"cannot release mutex"); return (-1); } return 0; }
/* * @implemented */ BOOL WINAPI ReleaseMutex(IN HANDLE hMutex) { NTSTATUS Status; /* Release the mutant */ Status = NtReleaseMutant(hMutex, NULL); if (NT_SUCCESS(Status)) return TRUE; /* If we got here, then we failed */ BaseSetLastNTError(Status); return FALSE; }
BOOL ReleaseMutex( HANDLE hMutex ) /*++ Routine Description: Ownership of a mutex object can be released with the ReleaseMutex function. A mutex object can only be released by a thread that currently owns the mutex object. When the mutex is released, the current count of the mutex object is incremented by one. If the resultant count is one, then the mutex object is no longer owned. Any threads that are waiting for the mutex object are examined to see if their wait can be satisfied. Arguments: hMutex - An open handle to a mutex object. The handle must have MUTEX_MODIFY_STATE access to the mutex. Return Value: TRUE - The operation was successful FALSE/NULL - The operation failed. Extended error status is available using GetLastError. --*/ { NTSTATUS Status; Status = NtReleaseMutant(hMutex,NULL); if ( NT_SUCCESS(Status) ) { return TRUE; } else { BaseSetLastNTError(Status); return FALSE; } }
ULONG BaseSrvNlsSetUserInfo( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { PBASE_NLS_SET_USER_INFO_MSG a = (PBASE_NLS_SET_USER_INFO_MSG)&m->u.ApiMessageData; ULONG rc; /* return code */ /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); /* * Set the value in the registry and update the cache. */ rc = NlsSetRegAndCache( a->pValue, a->pCacheString, a->pData, a->DataLength ); /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); /* * Return the result of NtSetValueKey. */ return (rc); ReplyStatus; // get rid of unreferenced parameter warning message }
DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) //Dynamic detect ITH main module status. { int i; TextHook *man; struct { DWORD pid; TextHook *man; DWORD module; DWORD engine; } u; HANDLE hMutex,hPipeExist; //swprintf(engine_event,L"ITH_ENGINE_%d",current_process_id); swprintf(detach_mutex,L"ITH_DETACH_%d",current_process_id); //swprintf(lose_event,L"ITH_LOSEPIPE_%d",current_process_id); //hEngine=IthCreateEvent(engine_event); //NtWaitForSingleObject(hEngine,0,0); //NtClose(hEngine); while (engine_base == 0) NtDelayExecution(0, &wait_time); //LoadEngine(L"ITH_Engine.dll"); u.module=module_base; u.pid=current_process_id; u.man=hookman; u.engine=engine_base; hPipeExist=IthOpenEvent(exist); IO_STATUS_BLOCK ios; //hLose=IthCreateEvent(lose_event,0,0); if (hPipeExist!=INVALID_HANDLE_VALUE) while (running) { hPipe=INVALID_HANDLE_VALUE; hCommand=INVALID_HANDLE_VALUE; while (NtWaitForSingleObject(hPipeExist,0,&wait_time)==WAIT_TIMEOUT) if (!running) goto _release; hMutex=IthCreateMutex(mutex,0); NtWaitForSingleObject(hMutex,0,0); while (hPipe==INVALID_HANDLE_VALUE|| hCommand==INVALID_HANDLE_VALUE) { NtDelayExecution(0,&sleep_time); if (hPipe==INVALID_HANDLE_VALUE) hPipe=IthOpenPipe(recv_pipe,GENERIC_WRITE); if (hCommand==INVALID_HANDLE_VALUE) hCommand=IthOpenPipe(command,GENERIC_READ); } //NtClearEvent(hLose); NtWriteFile(hPipe,0,0,0,&ios,&u,16,0,0); live=true; for (man=hookman,i=0;i<current_hook;man++) if (man->RecoverHook()) i++; OutputConsole(dll_name); OutputConsole(L"Pipe connected."); //OutputDWORD(tree->Count()); NtReleaseMutant(hMutex,0); NtClose(hMutex); if (!hook_inserted && engine_base) { hook_inserted=true; IdentifyEngine(); } hDetach=IthCreateMutex(detach_mutex,1); while (running&&NtWaitForSingleObject(hPipeExist,0,&sleep_time)==WAIT_OBJECT_0) NtDelayExecution(0,&sleep_time); live=false; for (man=hookman,i=0;i<current_hook;man++) if (man->RemoveHook()) i++; if (!running) { NtWriteFile(hPipe,0,0,0,&ios,man,4,0,0); IthReleaseMutex(hDetach); } NtClose(hDetach); NtClose(hPipe); } _release: //NtClose(hLose); NtClose(hPipeExist); return 0; }
VOID DoPaste( IN PCONSOLE_INFORMATION Console ) /*++ Perform paste request into old app by sucking out clipboard contents and writing them to the console's input buffer --*/ { BOOL Success; HANDLE ClipboardDataHandle; if (Console->Flags & CONSOLE_SCROLLING) { return; } // // Get paste data from clipboard // Success = OpenClipboard(Console->hWnd); if (!Success) return; if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { PWCHAR pwstr; ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT); if (ClipboardDataHandle == NULL) { CloseClipboard(); // Close clipboard return; } pwstr = GlobalLock(ClipboardDataHandle); DoStringPaste(Console,pwstr,GlobalSize(ClipboardDataHandle)); GlobalUnlock(ClipboardDataHandle); } else { HBITMAP hBitmapSource,hBitmapTarget; HDC hDCMemSource,hDCMemTarget; BITMAP bm; PSCREEN_INFORMATION ScreenInfo; hBitmapSource = GetClipboardData(CF_BITMAP); if (hBitmapSource) { ScreenInfo = Console->CurrentScreenBuffer; NtWaitForSingleObject(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, FALSE, NULL); hBitmapTarget = CreateDIBitmap(ScreenInfo->Console->hDC, &ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader, CBM_INIT, ScreenInfo->BufferInfo.GraphicsInfo.BitMap, ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo, ScreenInfo->BufferInfo.GraphicsInfo.dwUsage ); if (hBitmapTarget) { hDCMemTarget = CreateCompatibleDC ( Console->hDC ); hDCMemSource = CreateCompatibleDC ( Console->hDC ); SelectObject( hDCMemTarget, hBitmapTarget ); SelectObject( hDCMemSource, hBitmapSource ); GetObjectW(hBitmapSource, sizeof (BITMAP), (LPSTR) &bm); BitBlt ( hDCMemTarget, 0, 0, bm.bmWidth, bm.bmHeight, hDCMemSource, 0, 0, SRCCOPY); GetObjectW(hBitmapTarget, sizeof (BITMAP), (LPSTR) &bm); // copy the bits from the DC to memory GetDIBits(hDCMemTarget, hBitmapTarget, 0, bm.bmHeight, ScreenInfo->BufferInfo.GraphicsInfo.BitMap, ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo, ScreenInfo->BufferInfo.GraphicsInfo.dwUsage); DeleteDC(hDCMemSource); DeleteDC(hDCMemTarget); DeleteObject(hBitmapTarget); InvalidateRect(Console->hWnd,NULL,FALSE); // force repaint } NtReleaseMutant(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, NULL); } } CloseClipboard(); return; }
VOID StoreSelection( IN PCONSOLE_INFORMATION Console ) /*++ StoreSelection - Store selection (if present) into the Clipboard --*/ { PCHAR_INFO Selection,CurCharInfo; COORD SourcePoint; COORD TargetSize; SMALL_RECT TargetRect; PWCHAR CurChar,CharBuf; HANDLE ClipboardDataHandle; SHORT i,j; BOOL Success; PSCREEN_INFORMATION ScreenInfo; BOOL bFalseUnicode; // // See if there is a selection to get // if (!(Console->SelectionFlags & CONSOLE_SELECTION_NOT_EMPTY)) { return; } // // read selection rectangle. clip it first. // ScreenInfo = Console->CurrentScreenBuffer; if (Console->SelectionRect.Left < 0) { Console->SelectionRect.Left = 0; } if (Console->SelectionRect.Top < 0) { Console->SelectionRect.Top = 0; } if (Console->SelectionRect.Right >= ScreenInfo->ScreenBufferSize.X) { Console->SelectionRect.Right = (SHORT)(ScreenInfo->ScreenBufferSize.X-1); } if (Console->SelectionRect.Bottom >= ScreenInfo->ScreenBufferSize.Y) { Console->SelectionRect.Bottom = (SHORT)(ScreenInfo->ScreenBufferSize.Y-1); } TargetSize.X = WINDOW_SIZE_X(&Console->SelectionRect); TargetSize.Y = WINDOW_SIZE_Y(&Console->SelectionRect); if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) { Selection = (PCHAR_INFO)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),sizeof(CHAR_INFO) * TargetSize.X * TargetSize.Y); if (Selection == NULL) return; #ifdef _X86_ if ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) && (Console->Flags & CONSOLE_VDM_REGISTERED)) { ReadRegionFromScreenHW(ScreenInfo, &Console->SelectionRect, Selection); } else { #endif SourcePoint.X = Console->SelectionRect.Left; SourcePoint.Y = Console->SelectionRect.Top; TargetRect.Left = TargetRect.Top = 0; TargetRect.Right = (SHORT)(TargetSize.X-1); TargetRect.Bottom = (SHORT)(TargetSize.Y-1); ReadRectFromScreenBuffer(ScreenInfo, SourcePoint, Selection, TargetSize, &TargetRect); #ifdef _X86_ } #endif // extra 2 per line is for CRLF, extra 1 is for null ClipboardDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (TargetSize.Y * (TargetSize.X + 2) + 1) * sizeof(WCHAR)); if (ClipboardDataHandle == NULL) { HeapFree(pConHeap,0,Selection); return; } // // convert to clipboard form // CurCharInfo = Selection; CurChar = CharBuf = GlobalLock(ClipboardDataHandle); bFalseUnicode = ((ScreenInfo->Flags & CONSOLE_OEMFONT_DISPLAY) && !(Console->FullScreenFlags & CONSOLE_FULLSCREEN)); for (i=0;i<TargetSize.Y;i++) { PWCHAR pwchLineStart = CurChar; for (j=0;j<TargetSize.X;j++,CurCharInfo++,CurChar++) { *CurChar = CurCharInfo->Char.UnicodeChar; if (*CurChar == 0) { *CurChar = UNICODE_SPACE; } } // trim trailing spaces CurChar--; while ((CurChar >= pwchLineStart) && (*CurChar == UNICODE_SPACE)) CurChar--; CurChar++; if (bFalseUnicode) { FalseUnicodeToRealUnicode(pwchLineStart, CurChar - pwchLineStart, Console->OutputCP); } *CurChar++ = UNICODE_CARRIAGERETURN; *CurChar++ = UNICODE_LINEFEED; } if (TargetSize.Y) CurChar -= 2; // don't put CRLF on last line *CurChar = '\0'; // null terminate GlobalUnlock(ClipboardDataHandle); HeapFree(pConHeap,0,Selection); Success = OpenClipboard(Console->hWnd); if (!Success) { GlobalFree(ClipboardDataHandle); return; } Success = EmptyClipboard(); if (!Success) { GlobalFree(ClipboardDataHandle); return; } SetClipboardData(CF_UNICODETEXT,ClipboardDataHandle); CloseClipboard(); // Close clipboard } else { HBITMAP hBitmapTarget, hBitmapOld; HDC hDCMem; HPALETTE hPaletteOld; int Height; NtWaitForSingleObject(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, FALSE, NULL); hDCMem = CreateCompatibleDC(Console->hDC); hBitmapTarget = CreateCompatibleBitmap(Console->hDC, TargetSize.X, TargetSize.Y); if (hBitmapTarget) { hBitmapOld = SelectObject(hDCMem, hBitmapTarget); if (ScreenInfo->hPalette) { hPaletteOld = SelectPalette(hDCMem, ScreenInfo->hPalette, FALSE); } MyInvert(Console,&Console->SelectionRect); // if (DIB is a top-down) // ySrc = abs(height) - rect.bottom - 1; // else // ySrc = rect.Bottom. // Height = ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader.biHeight; StretchDIBits(hDCMem, 0, 0, TargetSize.X, TargetSize.Y, Console->SelectionRect.Left + ScreenInfo->Window.Left, (Height < 0) ? -Height - (Console->SelectionRect.Bottom + ScreenInfo->Window.Top) - 1 : Console->SelectionRect.Bottom + ScreenInfo->Window.Top, TargetSize.X, TargetSize.Y, ScreenInfo->BufferInfo.GraphicsInfo.BitMap, ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo, ScreenInfo->BufferInfo.GraphicsInfo.dwUsage, SRCCOPY); MyInvert(Console,&Console->SelectionRect); if (ScreenInfo->hPalette) { SelectPalette(hDCMem, hPaletteOld, FALSE); } SelectObject(hDCMem, hBitmapOld); OpenClipboard(Console->hWnd); EmptyClipboard(); SetClipboardData(CF_BITMAP,hBitmapTarget); CloseClipboard(); } DeleteDC(hDCMem); NtReleaseMutant(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, NULL); } }
VOID WeUnlockServerSharedData( VOID ) { NtReleaseMutant(WeServerSharedSectionLock, NULL); }
PPH_LIST EnumerateAppDomainIpcBlockWow64( _In_ HANDLE ProcessHandle, _In_ AppDomainEnumerationIPCBlock_Wow64* AppDomainIpcBlock ) { LARGE_INTEGER timeout; SIZE_T appDomainInfoBlockLength; HANDLE legacyPrivateBlockMutexHandle = NULL; AppDomainEnumerationIPCBlock_Wow64 tempBlock; AppDomainInfo_Wow64* appDomainInfoBlock = NULL; PPH_LIST appDomainsList = PhCreateList(1); // If the mutex isn't filled in, the CLR is either starting up or shutting down if (!AppDomainIpcBlock->Mutex) { goto CleanupExit; } // Dup the valid mutex handle into this process. if (!NT_SUCCESS(NtDuplicateObject( ProcessHandle, UlongToHandle(AppDomainIpcBlock->Mutex), NtCurrentProcess(), &legacyPrivateBlockMutexHandle, GENERIC_ALL, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES ))) { goto CleanupExit; } // Acquire the mutex, only waiting two seconds. // We can't actually gaurantee that the target put a mutex object in here. if (NtWaitForSingleObject( legacyPrivateBlockMutexHandle, FALSE, PhTimeoutFromMilliseconds(&timeout, 2000) ) == STATUS_WAIT_0) { // Make sure the mutex handle is still valid. If its not, then we lost a shutdown race. if (!AppDomainIpcBlock->Mutex) { goto CleanupExit; } } else { // Again, landing here is most probably a shutdown race. goto CleanupExit; } // Beware: If the target pid is not properly honoring the mutex, the data in the IPC block may still shift underneath us. // If we get here, then hMutex is held by this process. // Make a copy of the IPC block so that we can gaurantee that it's not changing on us. memcpy(&tempBlock, AppDomainIpcBlock, sizeof(AppDomainEnumerationIPCBlock_Wow64)); // It's possible the process will not have any appdomains. if ((tempBlock.ListOfAppDomains == 0) != (tempBlock.SizeInBytes == 0)) { goto CleanupExit; } // All the data in the IPC block is signed integers. They should never be negative, // so check that now. if ((tempBlock.TotalSlots < 0) || (tempBlock.NumOfUsedSlots < 0) || (tempBlock.LastFreedSlot < 0) || (tempBlock.SizeInBytes < 0) || (tempBlock.ProcessNameLengthInBytes < 0)) { goto CleanupExit; } // Allocate memory to read the remote process' memory into appDomainInfoBlockLength = tempBlock.SizeInBytes; // Check other invariants. if (appDomainInfoBlockLength != tempBlock.TotalSlots * sizeof(AppDomainInfo_Wow64)) { goto CleanupExit; } appDomainInfoBlock = (AppDomainInfo_Wow64*)PhAllocate(appDomainInfoBlockLength); memset(appDomainInfoBlock, 0, appDomainInfoBlockLength); if (!NT_SUCCESS(NtReadVirtualMemory( ProcessHandle, UlongToPtr(tempBlock.ListOfAppDomains), appDomainInfoBlock, appDomainInfoBlockLength, NULL ))) { PhFree(appDomainInfoBlock); goto CleanupExit; } // Collect all the AppDomain names into a list of strings. for (INT i = 0; i < tempBlock.NumOfUsedSlots; i++) { SIZE_T appDomainNameLength; PVOID appDomainName; if (!appDomainInfoBlock[i].AppDomainName) continue; // Should be positive, and at least have a null-terminator character. if (appDomainInfoBlock[i].NameLengthInBytes <= 1) continue; // Make sure buffer has right geometry. if (appDomainInfoBlock[i].NameLengthInBytes < 0) continue; // If it's not on a WCHAR boundary, then we may have a 1-byte buffer-overflow. appDomainNameLength = appDomainInfoBlock[i].NameLengthInBytes / sizeof(WCHAR); if ((appDomainNameLength * sizeof(WCHAR)) != appDomainInfoBlock[i].NameLengthInBytes) continue; // It should at least have 1 char for the null terminator. if (appDomainNameLength < 1) continue; // We know the string is a well-formed null-terminated string, // but beyond that, we can't verify that the data is actually truthful. appDomainName = PhAllocate(appDomainInfoBlock[i].NameLengthInBytes + 1); memset(appDomainName, 0, appDomainInfoBlock[i].NameLengthInBytes + 1); if (!NT_SUCCESS(NtReadVirtualMemory( ProcessHandle, UlongToPtr(appDomainInfoBlock[i].AppDomainName), appDomainName, appDomainInfoBlock[i].NameLengthInBytes, NULL ))) { PhFree(appDomainName); continue; } PhAddItemList(appDomainsList, appDomainName); } CleanupExit: if (appDomainInfoBlock) { PhFree(appDomainInfoBlock); } if (legacyPrivateBlockMutexHandle) { NtReleaseMutant(legacyPrivateBlockMutexHandle, NULL); NtClose(legacyPrivateBlockMutexHandle); } return appDomainsList; }
VOID NlsUpdateCacheInfo() { LCID Locale; /* locale id */ UNICODE_STRING ObKeyName; /* key name */ LPWSTR pTmp; /* tmp string pointer */ int ctr; /* loop counter */ ULONG ResultLength; /* result length */ ULONG rc = 0L; /* return code */ BYTE KeyValuePart[MAX_KEY_VALUE_PARTINFO]; PKEY_VALUE_PARTIAL_INFORMATION pValuePart; /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); /* * Update the cache information. */ pTmp = (LPWSTR)pNlsRegUserInfo; pValuePart = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValuePart; for (ctr = 0; ctr < NumCPanelRegValues; ctr++) { RtlInitUnicodeString( &ObKeyName, pCPanelRegValues[ctr] ); rc = NtQueryValueKey( hCPanelIntlKeyRead, &ObKeyName, KeyValuePartialInformation, pValuePart, MAX_KEY_VALUE_PARTINFO, &ResultLength ); if (NT_SUCCESS( rc )) { ((LPBYTE)pValuePart)[ResultLength] = UNICODE_NULL; wcscpy(pTmp, (LPWSTR)(pValuePart->Data)); } else { *pTmp = NLS_INVALID_INFO_CHAR; *(pTmp + 1) = UNICODE_NULL; } /* * Increment pointer to cache structure. */ pTmp += MAX_REG_VAL_SIZE; } /* * Convert the user locale id string to a dword value and store * it in the cache. */ pNlsRegUserInfo->UserLocaleId = (LCID)0; if ((pNlsRegUserInfo->sLocale)[0] != NLS_INVALID_INFO_CHAR) { RtlInitUnicodeString( &ObKeyName, pNlsRegUserInfo->sLocale ); if (NT_SUCCESS(RtlUnicodeStringToInteger( &ObKeyName, 16, &Locale ))) { pNlsRegUserInfo->UserLocaleId = Locale; } } /* * Make sure the user locale id was found. Otherwise, set it to * the system locale. */ if (pNlsRegUserInfo->UserLocaleId == 0) { NtQueryDefaultLocale( FALSE, &(pNlsRegUserInfo->UserLocaleId) ); } /* * Set the cache to be valid. */ pNlsRegUserInfo->fCacheValid = TRUE; /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); }
ULONG BaseSrvNlsSetMultipleUserInfo( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { PBASE_NLS_SET_MULTIPLE_USER_INFO_MSG a = (PBASE_NLS_SET_MULTIPLE_USER_INFO_MSG)&m->u.ApiMessageData; ULONG rc = 0L; /* return code */ /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); switch (a->Flags) { case ( LOCALE_STIMEFORMAT ) : { rc = NlsSetRegAndCache( NLS_VALUE_STIMEFORMAT, pNlsRegUserInfo->sTimeFormat, a->pPicture, a->DataLength ); if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_STIME, pNlsRegUserInfo->sTime, a->pSeparator, (wcslen(a->pSeparator) + 1) * sizeof(WCHAR) ); } if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_ITIME, pNlsRegUserInfo->iTime, a->pOrder, (wcslen(a->pOrder) + 1) * sizeof(WCHAR) ); } if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_ITLZERO, pNlsRegUserInfo->iTLZero, a->pTLZero, (wcslen(a->pTLZero) + 1) * sizeof(WCHAR) ); } if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_ITIMEMARKPOSN, pNlsRegUserInfo->iTimeMarkPosn, a->pTimeMarkPosn, (wcslen(a->pTimeMarkPosn) + 1) * sizeof(WCHAR) ); } break; } case ( LOCALE_STIME ) : { rc = NlsSetRegAndCache( NLS_VALUE_STIME, pNlsRegUserInfo->sTime, a->pSeparator, a->DataLength ); if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_STIMEFORMAT, pNlsRegUserInfo->sTimeFormat, a->pPicture, (wcslen(a->pPicture) + 1) * sizeof(WCHAR) ); } break; } case ( LOCALE_ITIME ) : { rc = NlsSetRegAndCache( NLS_VALUE_ITIME, pNlsRegUserInfo->iTime, a->pOrder, a->DataLength ); if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_STIMEFORMAT, pNlsRegUserInfo->sTimeFormat, a->pPicture, (wcslen(a->pPicture) + 1) * sizeof(WCHAR) ); } break; } case ( LOCALE_SSHORTDATE ) : { rc = NlsSetRegAndCache( NLS_VALUE_SSHORTDATE, pNlsRegUserInfo->sShortDate, a->pPicture, a->DataLength ); if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_SDATE, pNlsRegUserInfo->sDate, a->pSeparator, (wcslen(a->pSeparator) + 1) * sizeof(WCHAR) ); } if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_IDATE, pNlsRegUserInfo->iDate, a->pOrder, (wcslen(a->pOrder) + 1) * sizeof(WCHAR) ); } break; } case ( LOCALE_SDATE ) : { rc = NlsSetRegAndCache( NLS_VALUE_SDATE, pNlsRegUserInfo->sDate, a->pSeparator, a->DataLength ); if (NT_SUCCESS( rc )) { rc = NlsSetRegAndCache( NLS_VALUE_SSHORTDATE, pNlsRegUserInfo->sShortDate, a->pPicture, (wcslen(a->pPicture) + 1) * sizeof(WCHAR) ); } break; } } /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); /* * Return the result. */ return (rc); ReplyStatus; // get rid of unreferenced parameter warning message }
NTSTATUS BaseSrvNlsLogon( BOOL fLogon) { HANDLE hUserHandle; /* HKEY_CURRENT_USER equivalent */ HANDLE hKeyHandle; OBJECT_ATTRIBUTES ObjA; /* object attributes structure */ UNICODE_STRING ObKeyName; /* key name */ ULONG rc = 0L; /* return code */ if (fLogon) { /* * Logging ON. * - open keys * * NOTE: Registry Notification is done by the RIT in user server. */ rc = RtlOpenCurrentUser( MAXIMUM_ALLOWED, &hUserHandle ); if (!NT_SUCCESS( rc )) { KdPrint(("NLSAPI (BaseSrv): Could NOT Open HKEY_CURRENT_USER - %lx.\n", rc)); return ( rc ); } RtlInitUnicodeString( &ObKeyName, L"Control Panel\\International" ); InitializeObjectAttributes( &ObjA, &ObKeyName, OBJ_CASE_INSENSITIVE, hUserHandle, NULL ); /* * Open key for READ and NOTIFY access. */ rc = NtOpenKey( &hCPanelIntlKeyRead, KEY_READ | KEY_NOTIFY, &ObjA ); /* * Open key for WRITE access. */ if (!NT_SUCCESS( NtOpenKey( &hCPanelIntlKeyWrite, KEY_WRITE, &ObjA ) )) { KdPrint(("NLSAPI (BaseSrv): Could NOT Open Registry Key %wZ for Write - %lx.\n", &ObKeyName, rc)); hCPanelIntlKeyWrite = NULL; } /* * Close the handle to the current user (HKEY_CURRENT_USER). */ NtClose( hUserHandle ); /* * Check for error from first NtOpenKey. */ if (!NT_SUCCESS( rc )) { KdPrint(("NLSAPI (BaseSrv): Could NOT Open Registry Key %wZ for Read - %lx.\n", &ObKeyName, rc)); hCPanelIntlKeyRead = NULL; if (hCPanelIntlKeyWrite != NULL) { NtClose( hCPanelIntlKeyWrite ); hCPanelIntlKeyWrite = NULL; } return ( rc ); } } else { /* * Logging OFF. * - close keys * - zero out info */ if (hCPanelIntlKeyRead != NULL) { NtClose( hCPanelIntlKeyRead ); hCPanelIntlKeyRead = NULL; } if (hCPanelIntlKeyWrite != NULL) { NtClose( hCPanelIntlKeyWrite ); hCPanelIntlKeyWrite = NULL; } /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); /* * Set the cache to be invalid. */ pNlsRegUserInfo->fCacheValid = FALSE; /* * Zero out info. */ RtlZeroMemory(pNlsRegUserInfo, sizeof(NLS_USER_INFO)); /* * Make the system locale the user locale. */ NtQueryDefaultLocale( FALSE, &(pNlsRegUserInfo->UserLocaleId) ); /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); } /* * Return success. */ return ( STATUS_SUCCESS ); }