summaryrefslogtreecommitdiffstats
path: root/private/nw/convert/nwconv/utils.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/nw/convert/nwconv/utils.c830
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 ;
+ }
+}
+
+