diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/convert/nwconv/utils.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/nw/convert/nwconv/utils.c')
-rw-r--r-- | private/nw/convert/nwconv/utils.c | 830 |
1 files changed, 830 insertions, 0 deletions
diff --git a/private/nw/convert/nwconv/utils.c b/private/nw/convert/nwconv/utils.c new file mode 100644 index 000000000..5f1f03691 --- /dev/null +++ b/private/nw/convert/nwconv/utils.c @@ -0,0 +1,830 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + nwconv.c + +Abstract: + + +Author: + + Arthur Hanson (arth) 27-Jul-1994 + +Revision History: + +--*/ + + +#include "globals.h" + +LPTSTR alpsz[TOTAL_STRINGS]; // String resource array cache. +static UINT cswitch = 0; +static HCURSOR hCursor; + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +Lids( + WORD idsStr + ) + +/*++ + +Routine Description: + + Returns the requested string from the string table. Caches the + strings in an internal buffer. Will return a NULL string if the + string can't be loaded. + +Arguments: + + +Return Value: + + +--*/ + +{ + WORD idsString; + static TCHAR szEmpty[] = TEXT(""); + TCHAR Buffer[MAX_STRING_SIZE]; + + WORD nLen; + LPTSTR lpsz; + + idsString = idsStr - IDS_STRINGBASE; + if ((idsString == 0) ||( idsString > TOTAL_STRINGS)) + return(szEmpty); + + // -1 index as table is 0 based and 0 is not a valid string ID. + if (alpsz[idsString-1]) + return((LPTSTR)alpsz[idsString-1]); + + if (!(nLen = LoadString(hInst, idsStr, (LPTSTR) Buffer, MAX_STRING_SIZE))) + return(szEmpty); + + if (!(lpsz = AllocMemory((nLen+1) * sizeof(TCHAR)))) + return(szEmpty); + + lstrcpy((LPTSTR)lpsz, (LPTSTR) Buffer); + + return (alpsz[idsString-1] = lpsz); +} // Lids + + +///////////////////////////////////////////////////////////////////////// +VOID +StringTableDestroy() + +/*++ + +Routine Description: + + Frees up all the memory allocated in the string table. + +Arguments: + + +Return Value: + + +--*/ + +{ + int i; + + for (i=0; i < TOTAL_STRINGS ; i++ ) { + if (alpsz[i]) { + FreeMemory(alpsz[i]); + alpsz[i]=NULL; + } + } +} // StringTableDestroy + + +///////////////////////////////////////////////////////////////////////// +VOID +CursorHourGlass() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + if (!cswitch) { + hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); + ShowCursor(TRUE); + } + + cswitch++; + +} // CursorHourGlass + + +///////////////////////////////////////////////////////////////////////// +VOID +CursorNormal() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + + if (cswitch == 0) + return; + + cswitch--; + + if (!cswitch) { + ShowCursor(FALSE); + SetCursor(hCursor); + } + +} // Cursor Normal + + +///////////////////////////////////////////////////////////////////////// +BOOL +BitTest( + int Bit, + BYTE *Bits + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + int i, j; + + i = Bit / 8; + j = Bit % 8; + + if ((Bits[i] >> j) & 0x01) + return TRUE; + else + return FALSE; + +} // BitTest + + +///////////////////////////////////////////////////////////////////////// +BOOL +CenterWindow( + HWND hwndChild, + HWND hwndParent + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + RECT rChild, rParent; + int wChild, hChild, wParent, hParent; + int wScreen, hScreen, xNew, yNew; + HDC hdc; + + // Get the Height and Width of the child window + GetWindowRect (hwndChild, &rChild); + wChild = rChild.right - rChild.left; + hChild = rChild.bottom - rChild.top; + + // Get the Height and Width of the parent window + GetWindowRect (hwndParent, &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + + // Get the display limits + hdc = GetDC (hwndChild); + wScreen = GetDeviceCaps (hdc, HORZRES); + hScreen = GetDeviceCaps (hdc, VERTRES); + ReleaseDC (hwndChild, hdc); + + // Calculate new X position, then adjust for screen + xNew = rParent.left + ((wParent - wChild) /2); + if (xNew < 0) + xNew = 0; + else if ((xNew+wChild) > wScreen) + xNew = wScreen - wChild; + + // Calculate new Y position, then adjust for screen + yNew = rParent.top + ((hParent - hChild) /2); + if (yNew < 0) + yNew = 0; + else if ((yNew+hChild) > hScreen) + yNew = hScreen - hChild; + + // Set it, and return + return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + +} // CenterWindow + + +///////////////////////////////////////////////////////////////////////// +TCHAR * +lstrchr( + LPTSTR String, + TCHAR c + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR *ptrChar = String; + BOOL Found = FALSE; + + while(*ptrChar && !Found) { + if (*ptrChar == c) + Found = TRUE; + else + ptrChar++; + } + + if (Found) + return ptrChar; + else + return NULL; + +} // lstrchr + + +///////////////////////////////////////////////////////////////////////// +BOOL +IsPath( + LPTSTR Path + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + ULONG len; + LPTSTR ptr; + + len = lstrlen(Path); + if (len < 2) // must have a slash and character + return FALSE; + + // now know path is at least 2 characters long + ptr = Path; + + // if slash anywhere then it has to be a path + while (*ptr) + if (*ptr == TEXT('\\')) + return TRUE; + else + ptr++; + + // no slash - unless this is a drive then it aint no path. + if (Path[1] == TEXT(':')) + return TRUE; + + return FALSE; + +} // IsPath + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +lToStr( + ULONG Number + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR String[15]; + TCHAR tString[15]; + LPTSTR sptr, dptr; + ULONG Count; + + sptr = String; + dptr = tString; + wsprintf(tString, TEXT("%lu"), Number); + Count = lstrlen(tString); + + *sptr++ = *dptr++; + Count--; + + while (*dptr) { + if (!(Count % 3)) + *sptr++ = TEXT(','); + + *sptr++ = *dptr++; + Count--; + } + *sptr = TEXT('\0'); + + return String; +} // lToStr; + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +TimeToStr( + ULONG TotTime + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR String[10]; + ULONG Hours, Minutes, Seconds; + + Hours = TotTime / 3600; + TotTime -= (Hours * 3600); + Minutes = TotTime / 60; + Seconds = TotTime - (Minutes * 60); + + wsprintf(String, TEXT("%3lu:%2lu:%2lu"), Hours, Minutes, Seconds); + + return String; +} // TimeToStr; + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +DateToStr( + ULONG TotTime + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR String[10]; + ULONG Hours, Minutes, Seconds; + + Hours = TotTime / 3600; + TotTime -= (Hours * 3600); + Minutes = TotTime / 60; + Seconds = TotTime - (Minutes * 60); + + wsprintf(String, TEXT("%3lu:%2lu:%2lu"), Hours, Minutes, Seconds); + + return String; +} // DateToStr; + + +/*+-----------------------------------------------------------------------+ + | Took the _splitpath and _makepath routines and converted them to | + | be NT (long file name) and Unicode friendly. | + +-----------------------------------------------------------------------+*/ + + +///////////////////////////////////////////////////////////////////////// +VOID +lsplitpath( + const TCHAR *path, + TCHAR *drive, + TCHAR *dir, + TCHAR *fname, + TCHAR *ext + ) + +/*++ + +Routine Description: + + Splits a path name into its individual components + +Arguments: + + path - pointer to path name to be parsed + drive - pointer to buffer for drive component, if any + dir - pointer to buffer for subdirectory component, if any + fname - pointer to buffer for file base name component, if any + ext - pointer to buffer for file name extension component, if any + +Return Value: + + drive - pointer to drive string. Includes ':' if a drive was given. + dir - pointer to subdirectory string. Includes leading and + trailing '/' or '\', if any. + fname - pointer to file base name + ext - pointer to file extension, if any. Includes leading '.'. + +--*/ + +{ + TCHAR *p; + TCHAR *last_slash = NULL, *dot = NULL; + unsigned len; + + // init these so we don't exit with bogus values + drive[0] = TEXT('\0'); + dir[0] = TEXT('\0'); + fname[0] = TEXT('\0'); + ext[0] = TEXT('\0'); + + if (path[0] == TEXT('\0')) + return; + + /*+---------------------------------------------------------------------+ + | Assume that the path argument has the following form, where any or | + | all of the components may be missing. | + | | + | <drive><dir><fname><ext> | + | | + | drive: | + | 0 to MAX_DRIVE-1 characters, the last of which, if any, is a | + | ':' or a '\' in the case of a UNC path. | + | dir: | + | 0 to _MAX_DIR-1 characters in the form of an absolute path | + | (leading '/' or '\') or relative path, the last of which, if | + | any, must be a '/' or '\'. E.g - | + | | + | absolute path: | + | \top\next\last\ ; or | + | /top/next/last/ | + | relative path: | + | top\next\last\ ; or | + | top/next/last/ | + | Mixed use of '/' and '\' within a path is also tolerated | + | fname: | + | 0 to _MAX_FNAME-1 characters not including the '.' character | + | ext: | + | 0 to _MAX_EXT-1 characters where, if any, the first must be a | + | '.' | + +---------------------------------------------------------------------+*/ + + // extract drive letter and :, if any + if ( path[0] && (path[1] == TEXT(':')) ) { + if (drive) { + drive[0] = path[0]; + drive[1] = path[1]; + drive[2] = TEXT('\0'); + } + path += 2; + } + + // if no drive then check for UNC pathname + if (drive[0] == TEXT('\0')) + if ((path[0] == TEXT('\\')) && (path[1] == TEXT('\\'))) { + // got a UNC path so put server-sharename into drive + drive[0] = path[0]; + drive[1] = path[1]; + path += 2; + + p = &drive[2]; + while ((*path != TEXT('\0')) && (*path != TEXT('\\'))) + *p++ = *path++; + + if (*path == TEXT('\0')) + return; + + // now sitting at the share - copy this as well (copy slash first) + *p++ = *path++; + while ((*path != TEXT('\0')) && (*path != TEXT('\\'))) + *p++ = *path++; + + // tack on terminating NULL + *p = TEXT('\0'); + } + + /*+---------------------------------------------------------------------+ + | extract path string, if any. Path now points to the first character| + | of the path, if any, or the filename or extension, if no path was | + | specified. Scan ahead for the last occurence, if any, of a '/' or | + | '\' path separator character. If none is found, there is no path. | + | We will also note the last '.' character found, if any, to aid in | + | handling the extension. | + +---------------------------------------------------------------------+*/ + + for (last_slash = NULL, p = (TCHAR *)path; *p; p++) { + if (*p == TEXT('/') || *p == TEXT('\\')) + // point to one beyond for later copy + last_slash = p + 1; + else if (*p == TEXT('.')) + dot = p; + } + + if (last_slash) { + + // found a path - copy up through last_slash or max. characters allowed, + // whichever is smaller + if (dir) { + len = __min((last_slash - path), (_MAX_DIR - 1)); + lstrcpyn(dir, path, len + 1); + dir[len] = TEXT('\0'); + } + path = last_slash; + } + + /*+---------------------------------------------------------------------+ + | extract file name and extension, if any. Path now points to the | + | first character of the file name, if any, or the extension if no | + | file name was given. Dot points to the '.' beginning the extension,| + | if any. | + +---------------------------------------------------------------------+*/ + + if (dot && (dot >= path)) { + // found the marker for an extension - copy the file name up to the + // '.'. + if (fname) { + len = __min((dot - path), (_MAX_FNAME - 1)); + lstrcpyn(fname, path, len + 1); + *(fname + len) = TEXT('\0'); + } + + // now we can get the extension - remember that p still points to the + // terminating nul character of path. + if (ext) { + len = __min((p - dot), (_MAX_EXT - 1)); + lstrcpyn(ext, dot, len + 1); + ext[len] = TEXT('\0'); + } + } + else { + // found no extension, give empty extension and copy rest of string + // into fname. + if (fname) { + len = __min((p - path), (_MAX_FNAME - 1)); + lstrcpyn(fname, path, len + 1); + fname[len] = TEXT('\0'); + } + if (ext) { + *ext = TEXT('\0'); + } + } + +} // lsplitpath + + +///////////////////////////////////////////////////////////////////////// +VOID +lmakepath( + TCHAR *path, + const TCHAR *drive, + const TCHAR *dir, + const TCHAR *fname, + const TCHAR *ext + ) + +/*++ + +Routine Description: + + create a path name from its individual components. + +Arguments: + + char *path - pointer to buffer for constructed path + char *drive - pointer to drive component, may or may not contain + trailing ':' + char *dir - pointer to subdirectory component, may or may not include + leading and/or trailing '/' or '\' characters + char *fname - pointer to file base name component + char *ext - pointer to extension component, may or may not contain + a leading '.'. + +Return Value: + + path - pointer to constructed path name + +--*/ + +{ + const TCHAR *p; + + /*+---------------------------------------------------------------------+ + | we assume that the arguments are in the following form (although we | + | do not diagnose invalid arguments or illegal filenames (such as | + | names longer than 8.3 or with illegal characters in them) | + | | + | drive: | + | A or A: | + | dir: | + | \top\next\last\ ; or | + | /top/next/last/ ; or | + | | + | either of the above forms with either/both the leading and | + | trailing / or \ removed. Mixed use of '/' and '\' is also | + | tolerated | + | fname: | + | any valid file name | + | ext: | + | any valid extension (none if empty or null ) | + +---------------------------------------------------------------------+*/ + + // copy drive + if (drive && *drive) + while (*drive) + *path++ = *drive++; + + // copy dir + if ((p = dir) && *p) { + do { + *path++ = *p++; + } + while (*p); + if ((*(p-1) != TEXT('/')) && (*(p-1) != TEXT('\\'))) { + *path++ = TEXT('\\'); + } + } + + // copy fname + if (p = fname) { + while (*p) { + *path++ = *p++; + } + } + + // copy ext, including 0-terminator - check to see if a '.' needs to be + // inserted. + if (p = ext) { + if (*p && *p != TEXT('.')) { + *path++ = TEXT('.'); + } + while (*path++ = *p++) + ; + } + else { + // better add the 0-terminator + *path = TEXT('\0'); + } + +} // lmakepath + + +#ifndef _UNICODE +#error "Function below not DBCS safe" +#endif + +VOID +EscapeFormattingChars( + LPTSTR String, + ULONG BufferLength + ) + +/*++ + +Routine Description: + + Escapes any formatting chars (ie. % chars) in the string so + if you sprintf it, you dont trap out as a result of trying to + access bogus stack data. + +Arguments: + + String - String to fix up. Escaping is done IN PLACE. + BufferLength - Size of the buffer the string is in. We need to know + this since we are inserting characters. BufferLength is in + characters, not bytes. + +Return Value: + + None + +--*/ +{ + + + ULONG Length; LONG Avail ; + LPTSTR End, Tmp = String ; + + if (!Tmp) + return ; + + Length = lstrlen(String) ; + + // + // Point past end of string. We use this to figure out + // via pointer substraction how much needs to be shifted + // down as we insert chars. + // + End = Tmp + Length + 1 ; + + // + // How much is avail for escape chars + // + Avail = BufferLength - (Length+1) ; + + while (*Tmp) { + + if (*Tmp == TEXT('%')) { + + // + // If no more space, just change to '_'. + // + if (Avail <= 0) { + + *Tmp == TEXT('_') ; + } + else { + + // + // Move string over and add escape character. + // This is not very efficient but we assume + // that this is not common. + // + --Avail ; + memmove(Tmp+1, + Tmp, + ((LPBYTE)End - (LPBYTE)Tmp)) ; + *Tmp = TEXT('%') ; + Tmp++ ; + } + + + } + + ++Tmp ; + } +} + + |