windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/migdlls/scrnsamp/utils.c
2020-09-26 16:20:57 +08:00

692 lines
12 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
utils.c
Abstract:
This source file implements utility functions used by scrnsave.c.
Author:
Jim Schmidt (jimschm) 11-Apr-1997
Revision History:
--*/
#include "pch.h"
#ifdef UNICODE
#error UNICODE cannot be defined
#endif
//
// Declare strings
//
#define DEFMAC(var,str) CHAR var[] = str;
DEFINE_STRINGS
#undef DEFMAC
//
// Temporary buffer
//
static CHAR g_Data[MAX_PATH];
//
// Buffer for string representation of registry keys (for error logging)
//
typedef struct _tagKEYTOSTR {
struct _tagKEYTOSTR *Prev, *Next;
HKEY Key;
CHAR RegKey[];
} KEYTOSTR, *PKEYTOSTR;
static PKEYTOSTR g_Head = NULL;
VOID
pAddKeyToStrMapping (
IN HKEY Key,
IN LPCSTR RootStr,
IN LPCSTR KeyStr
)
{
PKEYTOSTR Node;
DWORD Size;
CHAR FullKeyStr[MAX_PATH];
// We control RootStr and KeyStr, so we know it is less than MAX_PATH in length
wsprintf (FullKeyStr, "%s\\%s", RootStr, KeyStr);
Size = sizeof (KEYTOSTR) + CountStringBytes (FullKeyStr);
Node = (PKEYTOSTR) HeapAlloc (g_hHeap, 0, Size);
if (Node) {
Node->Prev = NULL;
Node->Next = g_Head;
Node->Key = Key;
_mbscpy (Node->RegKey, FullKeyStr);
if (g_Head) {
g_Head->Prev = Node;
}
g_Head = Node;
}
}
PKEYTOSTR
pFindKeyToStrMapping (
IN HKEY Key
)
{
PKEYTOSTR Node;
Node = g_Head;
while (Node) {
if (Node->Key == Key) {
return Node;
}
Node = Node->Next;
}
return NULL;
}
VOID
pRemoveKeyToStrMapping (
IN HKEY Key
)
{
PKEYTOSTR Node;
Node = pFindKeyToStrMapping (Key);
if (!Node) {
return;
}
if (Node->Prev) {
Node->Prev->Next = Node->Next;
} else {
g_Head = Node->Next;
}
if (Node->Next) {
Node->Next->Prev = Node->Prev;
}
HeapFree (g_hHeap, 0, Node);
}
VOID
LogRegistryError (
IN HKEY Key,
IN LPCSTR ValueName
)
{
DWORD rc = GetLastError();
LPCSTR FullKeyStr;
PKEYTOSTR Node;
Node = pFindKeyToStrMapping (Key);
if (Node) {
FullKeyStr = Node->RegKey;
} else {
FullKeyStr = S_DEFAULT_KEYSTR;
}
LOG ((LOG_ERROR, MSG_REGISTRY_ERROR, g_User, rc, FullKeyStr, ValueName));
}
VOID
GenerateFilePaths (
VOID
)
{
INT Len;
// Safety (unexpected condition)
if (!g_WorkingDirectory) {
return;
}
Len = CountStringBytes (g_WorkingDirectory) + sizeof(S_SETTINGS_MASK);
g_SettingsFile = (LPSTR) HeapAlloc (g_hHeap, 0, Len);
if (!g_SettingsFile) {
return;
}
wsprintf (g_SettingsFile, S_SETTINGS_MASK, g_WorkingDirectory);
Len = CountStringBytes (g_WorkingDirectory) + sizeof(S_MIGINF_MASK);
g_MigrateDotInf = (LPSTR) HeapAlloc (g_hHeap, 0, Len);
if (!g_MigrateDotInf) {
return;
}
wsprintf (g_MigrateDotInf, S_MIGINF_MASK, g_WorkingDirectory);
}
HKEY
OpenRegKey (
IN HKEY RootKey,
IN LPCSTR KeyStr
)
{
HKEY Key;
LONG rc;
rc = RegOpenKeyEx (RootKey, KeyStr, 0, KEY_ALL_ACCESS, &Key);
if (rc != ERROR_SUCCESS) {
SetLastError (rc);
return NULL;
}
pAddKeyToStrMapping (Key, S_HKR, KeyStr);
return Key;
}
HKEY
CreateRegKey (
IN HKEY RootKey,
IN LPCSTR KeyStr
)
{
HKEY Key;
LONG rc;
DWORD DontCare;
pAddKeyToStrMapping (NULL, S_HKR, KeyStr);
rc = RegCreateKeyEx (RootKey, KeyStr, 0, S_EMPTY, 0,
KEY_ALL_ACCESS, NULL, &Key, &DontCare);
if (rc != ERROR_SUCCESS) {
SetLastError (rc);
LogRegistryError (NULL, S_EMPTY);
pRemoveKeyToStrMapping (NULL);
return NULL;
}
pRemoveKeyToStrMapping (NULL);
pAddKeyToStrMapping (Key, S_HKR, KeyStr);
return Key;
}
VOID
CloseRegKey (
IN HKEY Key
)
{
pRemoveKeyToStrMapping (Key);
RegCloseKey (Key);
}
LPCSTR
GetRegValueString (
IN HKEY Key,
IN LPCSTR ValueName
)
{
static CHAR DataBuf[MAX_PATH];
DWORD Size;
LONG rc;
DWORD Type;
DWORD d;
Size = MAX_PATH;
rc = RegQueryValueEx (Key, ValueName, NULL, &Type, DataBuf, &Size);
SetLastError (rc);
if (rc != ERROR_SUCCESS) {
return NULL;
}
if (Type == REG_DWORD) {
d = *((PDWORD) DataBuf);
wsprintf (DataBuf, "%u", d);
}
else if (Type != REG_SZ) {
return NULL;
}
return DataBuf;
}
BOOL
SetRegValueString (
HKEY Key,
LPCSTR ValueName,
LPCSTR ValueStr
)
{
LONG rc;
LPCSTR p;
p = _mbschr (ValueStr, 0);
p++;
rc = RegSetValueEx (Key, ValueName, 0, REG_SZ, ValueStr, p - ValueStr);
SetLastError (rc);
if (rc != ERROR_SUCCESS) {
LogRegistryError (Key, ValueName);
}
return rc == ERROR_SUCCESS;
}
LPCSTR
GetScrnSaveExe (
VOID
)
{
CHAR IniFileSetting[MAX_PATH];
GetPrivateProfileString (
S_BOOT,
S_SCRNSAVE_EXE,
S_EMPTY,
IniFileSetting,
MAX_PATH,
S_SYSTEM_INI
);
if (!IniFileSetting[0]) {
return NULL;
}
if (!OurGetLongPathName (IniFileSetting, g_Data)) {
// File does not exist
return NULL;
}
return g_Data[0] ? g_Data : NULL;
}
INT
_mbsbytes (
IN LPCSTR str
)
{
LPCSTR p;
// Find the nul terminator and return the number of bytes
// occupied by the characters in the string, but don't
// include the nul.
p = _mbschr (str, 0);
return (p - str);
}
DWORD
CountStringBytes (
IN LPCSTR str
)
{
// Return bytes in string, plus 1 for the nul
return _mbsbytes (str) + 1;
}
DWORD
CountMultiStringBytes (
IN LPCSTR str
)
{
LPCSTR p;
INT Total = 0;
INT Bytes;
p = str;
do {
Bytes = CountStringBytes (p);
p += Bytes;
Total += Bytes;
} while (Bytes > 1);
return Total;
}
LPSTR
CopyStringAtoB (
OUT LPSTR mbstrDest,
IN LPCSTR mbstrStart,
IN LPCSTR mbstrEnd // first char NOT to copy
)
{
LPSTR mbstrOrg;
mbstrOrg = mbstrDest;
// Assume mbstrEnd is on a lead byte
while (mbstrStart < mbstrEnd) {
if (isleadbyte (*mbstrStart)) {
*mbstrDest = *mbstrStart;
mbstrDest++;
mbstrStart++;
}
*mbstrDest = *mbstrStart;
mbstrDest++;
mbstrStart++;
}
*mbstrDest = 0;
return mbstrOrg;
}
LPSTR
AppendStr (
OUT LPSTR mbstrDest,
IN LPCSTR mbstrSrc
)
{
// Advance mbstrDest to end of string
mbstrDest = _mbschr (mbstrDest, 0);
// Copy string
while (*mbstrSrc) {
*mbstrDest = *mbstrSrc++;
if (isleadbyte (*mbstrDest)) {
mbstrDest++;
*mbstrDest = *mbstrSrc++;
}
mbstrDest++;
}
*mbstrDest = 0;
return mbstrDest;
}
BOOL
pFindShortName (
IN LPCTSTR WhatToFind,
OUT LPTSTR Buffer
)
{
WIN32_FIND_DATA fd;
HANDLE hFind;
hFind = FindFirstFile (WhatToFind, &fd);
if (hFind == INVALID_HANDLE_VALUE) {
return FALSE;
}
FindClose (hFind);
_mbscpy (Buffer, fd.cFileName);
return TRUE;
}
BOOL
OurGetLongPathName (
IN LPCSTR ShortPath,
OUT LPSTR Buffer
)
{
CHAR FullPath[MAX_PATH];
LPSTR FilePart;
LPSTR BufferEnd;
LPSTR p, p2;
CHAR c;
//
// Convert ShortPath into complete path name
//
if (!_mbschr (ShortPath, TEXT('\\'))) {
if (!SearchPath (NULL, ShortPath, NULL, MAX_PATH, FullPath, &FilePart)) {
return FALSE;
}
} else {
GetFullPathName (ShortPath, MAX_PATH, FullPath, &FilePart);
}
//
// Convert short path to long path
//
p = FullPath;
// Don't process non-local paths
if (!(*p) || _mbsnextc (_mbsinc (p)) != TEXT(':')) {
_mbscpy (Buffer, FullPath);
return TRUE;
}
p = _mbsinc (p);
p = _mbsinc (p);
if (_mbsnextc (p) != TEXT('\\')) {
_mbscpy (Buffer, FullPath);
return TRUE;
}
// Copy drive letter to buffer
p = _mbsinc (p);
CopyStringAtoB (Buffer, FullPath, p);
BufferEnd = _mbschr (Buffer, 0);
// Convert each portion of the path
do {
// Locate end of this file or dir
p2 = _mbschr (p, TEXT('\\'));
if (!p2) {
p = _mbschr (p, 0);
} else {
p = p2;
}
// Look up file
c = *p;
*p = 0;
if (!pFindShortName (FullPath, BufferEnd)) {
return FALSE;
}
*p = c;
// Move on to next part of path
BufferEnd = _mbschr (BufferEnd, 0);
if (*p) {
p = _mbsinc (p);
BufferEnd = AppendStr (BufferEnd, TEXT("\\"));
}
} while (*p);
return TRUE;
}
BOOL
CreateScreenSaverParamKey (
IN LPCSTR ScreenSaverName,
IN LPCSTR ValueName,
OUT LPSTR Buffer
)
{
//
// Make sure we cannot create a string bigger than MAX_PATH
//
if (_mbslen (ScreenSaverName) + 4 + _mbslen (ValueName) > MAX_PATH) {
return FALSE;
}
//
// Format the string with length of screen saver name, screen saver name,
// and value name.
//
wsprintf (Buffer, "%03u/%s/%s", _mbslen (ScreenSaverName), ScreenSaverName, ValueName);
return TRUE;
}
BOOL
DecodeScreenSaverParamKey (
IN LPCSTR EncodedString,
OUT LPSTR ScreenSaverName,
OUT LPSTR ValueName
)
{
INT Len;
//
// Validate encoded string. It is in the form of ###/screen saver name/value name.
//
Len = atoi (EncodedString);
if (Len < 0 || Len >= MAX_PATH || (Len - 5) > (INT) _mbslen (EncodedString)) {
return FALSE;
}
if (EncodedString[3] != '/' || EncodedString[4 + Len] != '/') {
return FALSE;
}
if (_mbslen (EncodedString + 5 + Len) >= MAX_PATH) {
return FALSE;
}
//
// Extract screen saver name and value name
//
_mbsncpy (ScreenSaverName, EncodedString + 4, Len);
ScreenSaverName[Len] = 0;
_mbscpy (ValueName, EncodedString + 5 + Len);
return TRUE;
}
LPSTR
_mbsistr (
IN LPCSTR mbstrStr,
IN LPCSTR mbstrSubStr
)
{
LPCSTR mbstrStart, mbstrStrPos, mbstrSubStrPos;
LPCSTR mbstrEnd;
mbstrEnd = (LPSTR) ((LPBYTE) mbstrStr + _mbsbytes (mbstrStr) - _mbsbytes (mbstrSubStr));
for (mbstrStart = mbstrStr ; mbstrStart <= mbstrEnd ; mbstrStart = _mbsinc (mbstrStart)) {
mbstrStrPos = mbstrStart;
mbstrSubStrPos = mbstrSubStr;
while (*mbstrSubStrPos &&
_mbctolower ((INT) _mbsnextc (mbstrSubStrPos)) == _mbctolower ((INT) _mbsnextc (mbstrStrPos)))
{
mbstrStrPos = _mbsinc (mbstrStrPos);
mbstrSubStrPos = _mbsinc (mbstrSubStrPos);
}
if (!(*mbstrSubStrPos))
return (LPSTR) mbstrStart;
}
return NULL;
}
VOID
DeletePartOfString (
IN LPSTR Buffer,
IN DWORD CharsToDelete
)
{
LPSTR p;
DWORD d;
p = Buffer;
for (d = 0 ; *p && d < CharsToDelete ; d++) {
p = _mbsinc (p);
}
if (!(*p)) {
*Buffer = 0;
} else {
MoveMemory (Buffer, p, CountStringBytes(p));
}
}
VOID
InsertStringInString (
IN LPSTR Buffer,
IN LPCSTR StringToInsert
)
{
DWORD BytesToMove;
DWORD BytesOfInsertedString;
BytesToMove = CountStringBytes (Buffer);
BytesOfInsertedString = _mbsbytes(StringToInsert);
MoveMemory (Buffer + BytesOfInsertedString,
Buffer,
BytesToMove
);
_mbsncpy (Buffer, StringToInsert, _mbslen (StringToInsert));
}
PCSTR
ParseMessage (
UINT MessageId,
...
)
{
va_list list;
PSTR RetStr = NULL;
UINT RetStrSize;
va_start (list, MessageId);
RetStrSize = FormatMessageA (
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
(PSTR) g_hInst,
MessageId,
0,
(PSTR) (&RetStr),
1,
&list
);
if (!RetStrSize && RetStr) {
*RetStr = 0;
}
va_end (list);
return RetStr;
}
VOID
FreeMessage (
PCSTR Message
)
{
if (Message) {
LocalFree ((PSTR) Message);
}
}