From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/nw/convert/dirs | 1 + private/nw/convert/logview/fv300.ico | Bin 0 -> 766 bytes private/nw/convert/logview/fvfile.c | 231 ++ private/nw/convert/logview/fvfind.c | 193 ++ private/nw/convert/logview/fvinit.c | 155 ++ private/nw/convert/logview/fvopen.c | 131 ++ private/nw/convert/logview/fvprint.c | 389 ++++ private/nw/convert/logview/logview.c | 767 +++++++ private/nw/convert/logview/logview.dlg | 51 + private/nw/convert/logview/logview.h | 214 ++ private/nw/convert/logview/logview.rc | 111 + private/nw/convert/logview/makefile | 6 + private/nw/convert/logview/note300.ico | Bin 0 -> 766 bytes private/nw/convert/logview/sources | 23 + private/nw/convert/logview/version.h | 52 + private/nw/convert/nwconv/aboutbox.c | 39 + private/nw/convert/nwconv/columnlb.c | 2986 ++++++++++++++++++++++++++ private/nw/convert/nwconv/columnlb.h | 329 +++ private/nw/convert/nwconv/constant.h | 36 + private/nw/convert/nwconv/convapi.h | 29 + private/nw/convert/nwconv/ctlspriv.h | 172 ++ private/nw/convert/nwconv/debug.c | 459 ++++ private/nw/convert/nwconv/debug.h | 34 + private/nw/convert/nwconv/encrypt.c | 328 +++ private/nw/convert/nwconv/error.c | 69 + private/nw/convert/nwconv/error.h | 19 + private/nw/convert/nwconv/fastcopy.c | 244 +++ private/nw/convert/nwconv/fcopy.c | 1162 ++++++++++ private/nw/convert/nwconv/filedlg.c | 1074 ++++++++++ private/nw/convert/nwconv/filedlg.h | 34 + private/nw/convert/nwconv/fileicon.bmp | Bin 0 -> 630 bytes private/nw/convert/nwconv/filesel.c | 2349 ++++++++++++++++++++ private/nw/convert/nwconv/filesel.h | 130 ++ private/nw/convert/nwconv/fpnwapi.h | 76 + private/nw/convert/nwconv/globals.h | 48 + private/nw/convert/nwconv/helpid.h | 70 + private/nw/convert/nwconv/hierchk.bmp | Bin 0 -> 502 bytes private/nw/convert/nwconv/hierdraw.c | 403 ++++ private/nw/convert/nwconv/hierdraw.h | 65 + private/nw/convert/nwconv/hierfile.c | 506 +++++ private/nw/convert/nwconv/hierfile.h | 74 + private/nw/convert/nwconv/hiericon.bmp | Bin 0 -> 886 bytes private/nw/convert/nwconv/loghours.c | 310 +++ private/nw/convert/nwconv/loghours.h | 52 + private/nw/convert/nwconv/makefile | 6 + private/nw/convert/nwconv/map.c | 1682 +++++++++++++++ private/nw/convert/nwconv/map.h | 62 + private/nw/convert/nwconv/mem.c | 381 ++++ private/nw/convert/nwconv/mem.h | 40 + private/nw/convert/nwconv/moveit.ico | Bin 0 -> 766 bytes private/nw/convert/nwconv/netutil.c | 437 ++++ private/nw/convert/nwconv/netutil.h | 87 + private/nw/convert/nwconv/ntnetapi.c | 3644 ++++++++++++++++++++++++++++++++ private/nw/convert/nwconv/ntnetapi.h | 85 + private/nw/convert/nwconv/ntsecapi.h | 28 + private/nw/convert/nwconv/nwconv.c | 1509 +++++++++++++ private/nw/convert/nwconv/nwconv.h | 25 + private/nw/convert/nwconv/nwconv.rc | 954 +++++++++ private/nw/convert/nwconv/nwlog.c | 746 +++++++ private/nw/convert/nwconv/nwlog.h | 39 + private/nw/convert/nwconv/nwnetapi.c | 2692 +++++++++++++++++++++++ private/nw/convert/nwconv/nwnetapi.h | 133 ++ private/nw/convert/nwconv/nwrights.h | 168 ++ private/nw/convert/nwconv/resource.h | 245 +++ private/nw/convert/nwconv/sbrowse.c | 1153 ++++++++++ private/nw/convert/nwconv/sbrowse.h | 44 + private/nw/convert/nwconv/servlist.c | 2094 ++++++++++++++++++ private/nw/convert/nwconv/servlist.h | 311 +++ private/nw/convert/nwconv/sizebarh.cur | Bin 0 -> 326 bytes private/nw/convert/nwconv/sources | 56 + private/nw/convert/nwconv/statbox.c | 568 +++++ private/nw/convert/nwconv/statbox.h | 46 + private/nw/convert/nwconv/strings.h | 478 +++++ private/nw/convert/nwconv/switches.h | 12 + private/nw/convert/nwconv/tab.c | 1512 +++++++++++++ private/nw/convert/nwconv/tab.h | 71 + private/nw/convert/nwconv/transfer.c | 2381 +++++++++++++++++++++ private/nw/convert/nwconv/transfer.h | 19 + private/nw/convert/nwconv/userdlg.c | 1266 +++++++++++ private/nw/convert/nwconv/userdlg.h | 49 + private/nw/convert/nwconv/usrprop.c | 592 ++++++ private/nw/convert/nwconv/usrprop.h | 77 + private/nw/convert/nwconv/utils.c | 830 ++++++++ private/nw/convert/nwconv/utils.h | 33 + private/nw/convert/nwconv/version.h | 52 + private/nw/convert/nwconv/vlist.h | 95 + private/nw/convert/nwconv/vlistint.h | 89 + 87 files changed, 38212 insertions(+) create mode 100644 private/nw/convert/dirs create mode 100644 private/nw/convert/logview/fv300.ico create mode 100644 private/nw/convert/logview/fvfile.c create mode 100644 private/nw/convert/logview/fvfind.c create mode 100644 private/nw/convert/logview/fvinit.c create mode 100644 private/nw/convert/logview/fvopen.c create mode 100644 private/nw/convert/logview/fvprint.c create mode 100644 private/nw/convert/logview/logview.c create mode 100644 private/nw/convert/logview/logview.dlg create mode 100644 private/nw/convert/logview/logview.h create mode 100644 private/nw/convert/logview/logview.rc create mode 100644 private/nw/convert/logview/makefile create mode 100644 private/nw/convert/logview/note300.ico create mode 100644 private/nw/convert/logview/sources create mode 100644 private/nw/convert/logview/version.h create mode 100644 private/nw/convert/nwconv/aboutbox.c create mode 100644 private/nw/convert/nwconv/columnlb.c create mode 100644 private/nw/convert/nwconv/columnlb.h create mode 100644 private/nw/convert/nwconv/constant.h create mode 100644 private/nw/convert/nwconv/convapi.h create mode 100644 private/nw/convert/nwconv/ctlspriv.h create mode 100644 private/nw/convert/nwconv/debug.c create mode 100644 private/nw/convert/nwconv/debug.h create mode 100644 private/nw/convert/nwconv/encrypt.c create mode 100644 private/nw/convert/nwconv/error.c create mode 100644 private/nw/convert/nwconv/error.h create mode 100644 private/nw/convert/nwconv/fastcopy.c create mode 100644 private/nw/convert/nwconv/fcopy.c create mode 100644 private/nw/convert/nwconv/filedlg.c create mode 100644 private/nw/convert/nwconv/filedlg.h create mode 100644 private/nw/convert/nwconv/fileicon.bmp create mode 100644 private/nw/convert/nwconv/filesel.c create mode 100644 private/nw/convert/nwconv/filesel.h create mode 100644 private/nw/convert/nwconv/fpnwapi.h create mode 100644 private/nw/convert/nwconv/globals.h create mode 100644 private/nw/convert/nwconv/helpid.h create mode 100644 private/nw/convert/nwconv/hierchk.bmp create mode 100644 private/nw/convert/nwconv/hierdraw.c create mode 100644 private/nw/convert/nwconv/hierdraw.h create mode 100644 private/nw/convert/nwconv/hierfile.c create mode 100644 private/nw/convert/nwconv/hierfile.h create mode 100644 private/nw/convert/nwconv/hiericon.bmp create mode 100644 private/nw/convert/nwconv/loghours.c create mode 100644 private/nw/convert/nwconv/loghours.h create mode 100644 private/nw/convert/nwconv/makefile create mode 100644 private/nw/convert/nwconv/map.c create mode 100644 private/nw/convert/nwconv/map.h create mode 100644 private/nw/convert/nwconv/mem.c create mode 100644 private/nw/convert/nwconv/mem.h create mode 100644 private/nw/convert/nwconv/moveit.ico create mode 100644 private/nw/convert/nwconv/netutil.c create mode 100644 private/nw/convert/nwconv/netutil.h create mode 100644 private/nw/convert/nwconv/ntnetapi.c create mode 100644 private/nw/convert/nwconv/ntnetapi.h create mode 100644 private/nw/convert/nwconv/ntsecapi.h create mode 100644 private/nw/convert/nwconv/nwconv.c create mode 100644 private/nw/convert/nwconv/nwconv.h create mode 100644 private/nw/convert/nwconv/nwconv.rc create mode 100644 private/nw/convert/nwconv/nwlog.c create mode 100644 private/nw/convert/nwconv/nwlog.h create mode 100644 private/nw/convert/nwconv/nwnetapi.c create mode 100644 private/nw/convert/nwconv/nwnetapi.h create mode 100644 private/nw/convert/nwconv/nwrights.h create mode 100644 private/nw/convert/nwconv/resource.h create mode 100644 private/nw/convert/nwconv/sbrowse.c create mode 100644 private/nw/convert/nwconv/sbrowse.h create mode 100644 private/nw/convert/nwconv/servlist.c create mode 100644 private/nw/convert/nwconv/servlist.h create mode 100644 private/nw/convert/nwconv/sizebarh.cur create mode 100644 private/nw/convert/nwconv/sources create mode 100644 private/nw/convert/nwconv/statbox.c create mode 100644 private/nw/convert/nwconv/statbox.h create mode 100644 private/nw/convert/nwconv/strings.h create mode 100644 private/nw/convert/nwconv/switches.h create mode 100644 private/nw/convert/nwconv/tab.c create mode 100644 private/nw/convert/nwconv/tab.h create mode 100644 private/nw/convert/nwconv/transfer.c create mode 100644 private/nw/convert/nwconv/transfer.h create mode 100644 private/nw/convert/nwconv/userdlg.c create mode 100644 private/nw/convert/nwconv/userdlg.h create mode 100644 private/nw/convert/nwconv/usrprop.c create mode 100644 private/nw/convert/nwconv/usrprop.h create mode 100644 private/nw/convert/nwconv/utils.c create mode 100644 private/nw/convert/nwconv/utils.h create mode 100644 private/nw/convert/nwconv/version.h create mode 100644 private/nw/convert/nwconv/vlist.h create mode 100644 private/nw/convert/nwconv/vlistint.h (limited to 'private/nw/convert') diff --git a/private/nw/convert/dirs b/private/nw/convert/dirs new file mode 100644 index 000000000..75b12589b --- /dev/null +++ b/private/nw/convert/dirs @@ -0,0 +1 @@ +DIRS=nwconv logview diff --git a/private/nw/convert/logview/fv300.ico b/private/nw/convert/logview/fv300.ico new file mode 100644 index 000000000..b68c9cb86 Binary files /dev/null and b/private/nw/convert/logview/fv300.ico differ diff --git a/private/nw/convert/logview/fvfile.c b/private/nw/convert/logview/fvfile.c new file mode 100644 index 000000000..466ec9c4c --- /dev/null +++ b/private/nw/convert/logview/fvfile.c @@ -0,0 +1,231 @@ +/* + +-------------------------------------------------------------------------+ + | MDI Text File Viewer - File IO Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [mpfile.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993 | + | Last Update : [Jul 30, 1993] Time : 18:30 | + | | + | Version: 0.10 | + | | + | Description: | + | | + | History: | + | arth Jul 27, 1993 0.10 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "LogView.h" +#include +#include +#include +#include +#include + +VOID APIENTRY GetFileName(HWND hwnd, PSTR); + +OFSTRUCT of; + + +/*+-------------------------------------------------------------------------+ + | AlreadyOpen() | + | | + | Checks to see if a file is already opened. Returns a handle to | + | the file's window if it is opened, otherwise NULL. | + | | + +-------------------------------------------------------------------------+*/ +HWND AlreadyOpen(CHAR *szFile) { + INT iDiff; + HWND hwndCheck; + CHAR szChild[64]; + LPSTR lpChild, lpFile; + HFILE wFileTemp; + + // Open the file with the OF_PARSE flag to obtain the fully qualified + // pathname in the OFSTRUCT structure. + wFileTemp = OpenFile((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE); + if (! wFileTemp) + return(NULL); + _lclose(wFileTemp); + + // Check each MDI child window in LogView + for ( hwndCheck = GetWindow(hwndMDIClient, GW_CHILD); + hwndCheck; + hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT) ) { + // Initialization for comparison + lpChild = szChild; + lpFile = (LPSTR)AnsiUpper((LPSTR) of.szPathName); + iDiff = 0; + + // Skip icon title windows + if (GetWindow(hwndCheck, GW_OWNER)) + continue; + + // Get current child window's name + GetWindowText(hwndCheck, lpChild, 64); + + // Compare window name with given name + while ((*lpChild) && (*lpFile) && (!iDiff)) { + if (*lpChild++ != *lpFile++) + iDiff = 1; + } + + // If the two names matched, the file is already open - return handle to matching + // child window. + if (!iDiff) + return(hwndCheck); + } + + // No match found -- file is not open -- return NULL handle + return(NULL); + +} // AlreadyOpen + + +/*+-------------------------------------------------------------------------+ + | AddFile() | + | | + | Create a new MDI Window, and loads specified file into Window. | + | | + +-------------------------------------------------------------------------+*/ +HWND APIENTRY AddFile(CHAR * pName) { + HWND hwnd; + + CHAR sz[160]; + MDICREATESTRUCT mcs; + + if (!pName) { + // The pName parameter is NULL -- load the "Untitled" string from STRINGTABLE + // and set the title field of the MDI CreateStruct. + LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz)); + mcs.szTitle = (LPSTR)sz; + } + else + // Title the window with the fully qualified pathname obtained by calling + // OpenFile() with the OF_PARSE flag (in function AlreadyOpen(), which is called + // before AddFile(). + mcs.szTitle = pName; + + mcs.szClass = szChild; + mcs.hOwner = hInst; + + // Use the default size for the window + mcs.x = mcs.cx = CW_USEDEFAULT; + mcs.y = mcs.cy = CW_USEDEFAULT; + + // Set the style DWORD of the window to default + mcs.style = 0L; + + // tell the MDI Client to create the child + hwnd = (HWND)SendMessage (hwndMDIClient, + WM_MDICREATE, + 0, + (LONG)(LPMDICREATESTRUCT)&mcs); + + // Did we get a file? Read it into the window + if (pName){ + if (!LoadFile(hwnd, pName)){ + // File couldn't be loaded -- close window + SendMessage(hwndMDIClient, WM_MDIDESTROY, (DWORD) hwnd, 0L); + } + } + + return hwnd; + +} // AddFile + + +/*+-------------------------------------------------------------------------+ + | LoadFile() | + | | + | Loads file into specified MDI window's edit control. | + | | + +-------------------------------------------------------------------------+*/ +INT APIENTRY LoadFile ( HWND hwnd, CHAR * pName) { + LONG wLength; + HANDLE hT; + LPSTR lpB; + HWND hwndEdit; + HFILE fh; + OFSTRUCT of; + + hwndEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT); + + // The file has a title, so reset the UNTITLED flag. + SetWindowWord(hwnd, GWW_UNTITLED, FALSE); + + fh = OpenFile(pName, &of, OF_READ); // JAP was 0, which is OF_READ) + + // Make sure file has been opened correctly + if ( fh < 0 ) + goto error; + + // Find the length of the file + wLength = (DWORD)_llseek(fh, 0L, 2); + _llseek(fh, 0L, 0); + + // Attempt to reallocate the edit control's buffer to the file size + hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L); + if (LocalReAlloc(hT, wLength+1, LHND) == NULL) { + // Couldn't reallocate to new size -- error + _lclose(fh); + goto error; + } + + // read the file into the buffer + if (wLength != (LONG)_lread(fh, (lpB = (LPSTR)LocalLock (hT)), (UINT)wLength)) + MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName); + + // Zero terminate the edit buffer + lpB[wLength] = 0; + LocalUnlock (hT); + + SendMessage (hwndEdit, EM_SETHANDLE, (UINT)hT, 0L); + _lclose(fh); + + return TRUE; + +error: + // Report the error and quit + MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName); + return FALSE; + +} // LoadFile + + +/*+-------------------------------------------------------------------------+ + | MyReadFile() | + | | + | Asks user for a filename. | + | | + +-------------------------------------------------------------------------+*/ +VOID APIENTRY MyReadFile(HWND hwnd) { + CHAR szFile[128]; + HWND hwndFile; + + GetFileName (hwnd, szFile); + + // If the result is not the empty string -- take appropriate action + if (*szFile) { + // Is file already open?? + if (hwndFile = AlreadyOpen(szFile)) { + // Yes -- bring the file's window to the top + BringWindowToTop(hwndFile); + } + else { + // No -- make a new window and load file into it + AddFile(szFile); + } + } + UNREFERENCED_PARAMETER(hwnd); + +} // MyReadFile + + + diff --git a/private/nw/convert/logview/fvfind.c b/private/nw/convert/logview/fvfind.c new file mode 100644 index 000000000..459469477 --- /dev/null +++ b/private/nw/convert/logview/fvfind.c @@ -0,0 +1,193 @@ +/* + +-------------------------------------------------------------------------+ + | MDI Text File Viewer - Text Search Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FVFind.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993 | + | Last Update : [Jul 30, 1993] Time : 18:30 | + | | + | Version: 0.10 | + | | + | Description: | + | | + | History: | + | arth Jul 27, 1993 0.10 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "LogView.h" +#include +#include + +#undef HIWORD +#undef LOWORD + +#define HIWORD(l) (((WORD*)&(l))[1]) +#define LOWORD(l) (((WORD*)&(l))[0]) + +BOOL fCase = FALSE; // Turn case sensitivity off +CHAR szSearch[160] = ""; // Initialize search string + + +extern HWND hDlgFind; /* handle to modeless FindText window */ + +LPTSTR ReverseScan( + LPTSTR lpSource, + LPTSTR lpLast, + LPTSTR lpSearch, + BOOL fCaseSensitive ) { + int iLen = lstrlen(lpSearch); + + if (!lpLast) + lpLast = lpSource + lstrlen(lpSource); + + do { + if (lpLast == lpSource) + return NULL; + + --lpLast; + + if (fCaseSensitive) { + if (*lpLast != *lpSearch) + continue; + } else { + if (CharUpper ((LPTSTR)MAKELONG((WORD)*lpLast, 0)) != CharUpper ((LPTSTR)MAKELONG((WORD)*lpSearch, 0))) + continue; + } + + if (fCaseSensitive) { + if (!strncmp( lpLast, lpSearch, iLen)) + break; + } else { + if (!_strnicmp (lpLast, lpSearch, iLen)) + break; + } + } while (TRUE); + + return lpLast; +} // ReverseScan + + +LPTSTR ForwardScan(LPTSTR lpSource, LPTSTR lpSearch, BOOL fCaseSensitive ) { + int iLen = lstrlen(lpSearch); + + while (*lpSource) { + if (fCaseSensitive) { + if (*lpSource != *lpSearch) { + lpSource++; + continue; + } + } else { + if (CharUpper ((LPTSTR)MAKELONG((WORD)*lpSource, 0)) != CharUpper ((LPTSTR)MAKELONG((WORD)*lpSearch, 0))) { + lpSource++; + continue; + } + } + + if (fCaseSensitive) { + if (!strncmp( lpSource, lpSearch, iLen)) + break; + } else { + if (!_strnicmp( lpSource, lpSearch, iLen)) + break; + } + + lpSource++; + } + + return *lpSource ? lpSource : NULL; +} // ForwardScan + + +// search forward or backward in the edit control text for the given pattern +void FAR Search (TCHAR * szKey) { + HANDLE hText; + TCHAR * pStart, *pMatch; + DWORD StartIndex, LineNum, EndIndex; + DWORD SelStart, SelEnd, i; + DWORD dwSel; + INT cbText; + + if (!*szKey) + return; + + SetCursor(hWaitCursor); + dwSel= SendMessage(hwndActiveEdit, EM_GETSEL, (WPARAM)&SelStart, (LPARAM)&SelEnd); + + /* + * Allocate hText and read edit control text into it. + * Lock hText and fall through to existing code. + */ + + cbText= SendMessage(hwndActiveEdit, WM_GETTEXTLENGTH, 0, 0L) + 1; + hText= LocalAlloc( LPTR, cbText ); + if( !hText ) // quiet exit if not enough memory + return; + if( !(pStart= LocalLock(hText)) ) { + LocalFree(hText); + return; + } + + SendMessage(hwndActiveEdit, WM_GETTEXT, cbText, (LPARAM)pStart); + + if (fReverse) { + // Get current line number + LineNum= SendMessage(hwndActiveEdit, EM_LINEFROMCHAR, SelStart, 0); + // Get index to start of the line + StartIndex= SendMessage(hwndActiveEdit, EM_LINEINDEX, LineNum, 0); + // Set upper limit for search text + EndIndex= SelStart; + pMatch= NULL; + + // Search line by line, from LineNum to 0 + i = LineNum; + while (TRUE) { + pMatch= ReverseScan(pStart+StartIndex,pStart+EndIndex,szKey,fCase); + if (pMatch) + break; + // current StartIndex is the upper limit for the next search + EndIndex= StartIndex; + + if (i) { + // Get start of the next line + i-- ; + StartIndex= SendMessage(hwndActiveEdit, EM_LINEINDEX, i, 0); + } else + break ; + } + } else { + pMatch= ForwardScan(pStart + SelEnd, szKey, fCase); + } + LocalUnlock(hText); + LocalFree( hText ); + SetCursor(hStdCursor); + + if (pMatch == NULL) { + TCHAR Message[256], AppName[256] ; + + if (!LoadString(hInst, IDS_CANTFINDSTR, Message, + sizeof(Message)/sizeof(Message[0]))) { + Message[0] = 0 ; + } + + if (!LoadString(hInst, IDS_APPNAME, AppName, + sizeof(AppName)/sizeof(AppName[0]))) { + AppName[0] = 0 ; + } + + MessageBox(hwndFrame, Message, AppName, + MB_APPLMODAL | MB_OK | MB_ICONASTERISK); + } else { + SelStart = pMatch - pStart; + SendMessage(hwndActiveEdit, EM_SETSEL, SelStart, SelStart+lstrlen(szKey)); + SendMessage(hwndActiveEdit, EM_SCROLLCARET, 0, 0); + } + +} // Search + diff --git a/private/nw/convert/logview/fvinit.c b/private/nw/convert/logview/fvinit.c new file mode 100644 index 000000000..11330fb2a --- /dev/null +++ b/private/nw/convert/logview/fvinit.c @@ -0,0 +1,155 @@ +/* + +-------------------------------------------------------------------------+ + | Initialization Code | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [mpinit.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993 | + | Last Update : [Jul 30, 1993] Time : 18:30 | + | | + | Version: 0.10 | + | | + | Description: | + | | + | History: | + | arth Jul 27, 1993 0.10 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ +#include "LogView.h" + +CHAR szFrame[] = "mpframe"; // Class name for "frame" window +CHAR szChild[] = "mpchild"; // Class name for MDI window + +/*+-------------------------------------------------------------------------+ + | InitializeApplication() | + | | + +-------------------------------------------------------------------------+*/ +BOOL APIENTRY InitializeApplication() { + WNDCLASS wc; + + // Register the frame class + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) MPFrameWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInst; + wc.hIcon = LoadIcon(hInst,IDLOGVIEW); + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1); + wc.lpszMenuName = IDLOGVIEW; + wc.lpszClassName = szFrame; + + if (!RegisterClass (&wc) ) + return FALSE; + + // Register the MDI child class + wc.lpfnWndProc = (WNDPROC) MPMDIChildWndProc; + wc.hIcon = LoadIcon(hInst,IDNOTE); + wc.lpszMenuName = NULL; + wc.cbWndExtra = CBWNDEXTRA; + wc.lpszClassName = szChild; + + if (!RegisterClass(&wc)) + return FALSE; + + return TRUE; + +} // InitializeApplication + + +/*+-------------------------------------------------------------------------+ + | InitializeInstance() | + | | + +-------------------------------------------------------------------------+*/ +BOOL APIENTRY InitializeInstance(LPSTR lpCmdLine, INT nCmdShow) { + extern HWND hwndMDIClient; + CHAR sz[80], *pCmdLine, *pFileName, *pChar; + HDC hdc; + HMENU hmenu; + + // Get the base window title + LoadString (hInst, IDS_APPNAME, sz, sizeof(sz)); + + hStdCursor= LoadCursor( NULL,IDC_ARROW ); + hWaitCursor= LoadCursor( NULL, IDC_WAIT ); + + // Create the frame + hwndFrame = CreateWindow (szFrame, sz, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, + NULL, hInst, NULL); + + if ((!hwndFrame) || (!hwndMDIClient)) + return FALSE; + + // Load main menu accelerators + if (!(hAccel = LoadAccelerators (hInst, IDLOGVIEW))) + return FALSE; + + // init.fields of the FINDREPLACE struct used by FindText() + FR.lStructSize = sizeof(FINDREPLACE); + FR.hwndOwner = hwndFrame; + FR.Flags = FR_DOWN | FR_HIDEWHOLEWORD; + FR.lpstrReplaceWith = (LPTSTR)NULL; + FR.wReplaceWithLen = 0; + FR.lpfnHook = NULL; + + /* determine the message number to be used for communication with + * Find dialog + */ + if (!(wFRMsg = RegisterWindowMessage ((LPTSTR)FINDMSGSTRING))) + return FALSE; + if (!(wHlpMsg = RegisterWindowMessage ((LPTSTR)HELPMSGSTRING))) + return FALSE; + + // Display the frame window + ShowWindow (hwndFrame, nCmdShow); + UpdateWindow (hwndFrame); + + // If the command line string is empty, nullify the pointer to it else copy + // command line into our data segment + if ( lpCmdLine && !(*lpCmdLine)) { + pCmdLine = NULL; + + // Add the first MDI window + AddFile (pCmdLine); + + } else { + pCmdLine = (CHAR *) LocalAlloc(LPTR, lstrlen(lpCmdLine) + 1); + + if (pCmdLine) { + lstrcpy(pCmdLine, lpCmdLine); + + pFileName = pChar = pCmdLine; + + while (*pChar) { + if (*pChar == ' ') { + *pChar = '\0'; + AddFile(pFileName); + *pChar = ' '; + pChar++; + pFileName = pChar; + } else + pChar++; + } + AddFile(pFileName); + + } else + + // Add the first MDI window + AddFile (pCmdLine); + } + + // if we allocated a buffer then free it + if (pCmdLine) + LocalFree((LOCALHANDLE) pCmdLine); + + return TRUE; + UNREFERENCED_PARAMETER(hmenu); + UNREFERENCED_PARAMETER(hdc); + +} // InitializeInstance diff --git a/private/nw/convert/logview/fvopen.c b/private/nw/convert/logview/fvopen.c new file mode 100644 index 000000000..97a0458eb --- /dev/null +++ b/private/nw/convert/logview/fvopen.c @@ -0,0 +1,131 @@ +/* + +-------------------------------------------------------------------------+ + | MDI Text File View - File open Functions | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FVOpen.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 11, 1994] | + | Last Update : [Feb 11, 1994] | + | | + | Version: 0.10 | + | | + | Description: | + | | + | History: | + | arth Jul 27, 1993 0.10 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "LogView.h" +#include +#include +#include + +#define MAXFILENAME 256 + + +CHAR szPropertyName [] = "FILENAME"; // Name of the File name property list item + + +///////////////////////////////////////////////////////////////////////// +BOOL +FileExists( + PSTR pch + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + int fh; + + if ((fh = _open(pch, O_RDONLY)) < 0) + return(FALSE); + + _lclose(fh); + return(TRUE); +} // FileExists + + +///////////////////////////////////////////////////////////////////////// +VOID APIENTRY +GetFileName( + HWND hwnd, + PSTR pstr + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + CHAR szFmt[128]; + OPENFILENAME ofn; + CHAR szFilterSpec[128]; + CHAR szDefExt[10]; + CHAR szFileName[MAXFILENAME]; + CHAR szFileTitle[MAXFILENAME]; + + strcpy(szFileName, ""); // these need be NULL + strcpy(szFileTitle, ""); + memset(&ofn,0,sizeof(ofn)) ; + memset(szFilterSpec,0,sizeof(szFilterSpec)) ; + + LoadString (hInst, (WORD)IDS_OPENTEXT, + (LPSTR)szFmt, sizeof (szFmt)); + LoadString (hInst, (WORD)IDS_OPENFILTER, + (LPSTR)szFilterSpec, sizeof (szFilterSpec)); + + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilterSpec; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 0; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAXFILENAME; + ofn.lpstrInitialDir = NULL; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = MAXFILENAME; + ofn.lpstrTitle = szFmt; + + LoadString (hInst, (WORD)IDS_DEFEXT, (LPSTR)szDefExt, sizeof (szDefExt)); + ofn.lpstrDefExt = szDefExt; + ofn.Flags = OFN_FILEMUSTEXIST; + + // Use standard open dialog + if (!GetOpenFileName ((LPOPENFILENAME)&ofn)) { + *pstr = 0; + } + else { + strcpy(pstr, ofn.lpstrFile); + } + + return; + +} // GetFileName diff --git a/private/nw/convert/logview/fvprint.c b/private/nw/convert/logview/fvprint.c new file mode 100644 index 000000000..675c46c8d --- /dev/null +++ b/private/nw/convert/logview/fvprint.c @@ -0,0 +1,389 @@ +/* + +-------------------------------------------------------------------------+ + | MDI Text File Viewer - Printing Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FVPrint.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 11, 1994] | + | Last Update : [Feb 11, 1994] | + | | + | Version: 0.10 | + | | + | Description: | + | | + | History: | + | arth Jul 27, 1993 0.10 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "LogView.h" + +BOOL fAbort; +HWND hwndPDlg; +CHAR szDevice[160]; +PSTR szDriver; +PSTR szPort; +PSTR szTitle; +INT iPrinter = 0; // level of available printer support. + // 0 - no printer available + // 1 - printer available + // 2 - driver supports 3.0 device initialization +HANDLE hInitData=NULL; + +CHAR szExtDeviceMode[] = "EXTDEVICEMODE"; + + +/*+-------------------------------------------------------------------------+ + | GetPrinterDC() | + | | + | Creates a printer display context for the default device. As a side | + | effect, it sets the szDevice and szPort variables. It also sets | + | iPrinter to the supported level of printing. | + | | + +-------------------------------------------------------------------------+*/ +HDC APIENTRY GetPrinterDC(BOOL bInformation) { + HDC hdc; + LPDEVMODE lpdevmode = NULL; + + iPrinter = 0; + + // Get the printer information from win.ini into a buffer and null terminate it. + GetProfileString ( TEXT("windows"), TEXT("device"), TEXT(""), szDevice, sizeof(szDevice)); + for (szDriver = szDevice; *szDriver && *szDriver != TEXT(','); szDriver++) + ; + if (*szDriver) + *szDriver++ = 0; + + // From the current position in the buffer, null teminate the list of ports + for (szPort = szDriver; *szPort && *szPort != TEXT(','); szPort++) + ; + if (*szPort) + *szPort++ = 0; + + // if the device, driver and port buffers all contain meaningful data, proceed. + if (!*szDevice || !*szDriver || !*szPort){ + *szDevice = 0; + return NULL; + } + + // Create the printer display context + if (hInitData){ + // Get a pointer to the initialization data + lpdevmode = (LPDEVMODE) LocalLock (hInitData); + + if (lstrcmp (szDevice, (LPSTR)lpdevmode)) { + // User has changed the device... cancel this setup, as it is invalid + // (although if we worked harder we could retain some of it). + lpdevmode = NULL; + LocalUnlock (hInitData); + LocalFree (hInitData); + hInitData = NULL; + } + } + + if (bInformation) + hdc = CreateIC (szDriver, szDevice, szPort, lpdevmode); + else + hdc = CreateDC (szDriver, szDevice, szPort, lpdevmode); + + // Unlock initialization data + if (hInitData) + LocalUnlock (hInitData); + + if (!hdc) + return NULL; + + + iPrinter = 1; + + // Find out if ExtDeviceMode() is supported and set flag appropriately + if (GetProcAddress (LoadLibrary(szDriver), szExtDeviceMode)) + iPrinter = 2; + + return hdc; + +} // GetPrinterDC + + +/*+-------------------------------------------------------------------------+ + | AbortProc() | + | | + | Checks for user abort. | + | | + +-------------------------------------------------------------------------+*/ +INT APIENTRY AbortProc ( HDC hdc, WORD reserved) { + MSG msg; + + // Allow other apps to run, or get abort messages + while (!fAbort && PeekMessage (&msg, NULL, 0, 0, TRUE)) + if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + return !fAbort; + + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(reserved); + +} // AbortProc + + +/*+-------------------------------------------------------------------------+ + | PrintDlgProc() | + | | + | Print/Cancel dialog box. | + | | + +-------------------------------------------------------------------------+*/ +BOOL APIENTRY PrintDlgProc(HWND hwnd, UINT msg, WORD wParam, LONG lParam) { + switch (msg) { + case WM_INITDIALOG: + // Set up information in dialog box + SetDlgItemText (hwnd, IDD_PRINTTITLE, (LPSTR)szTitle); + break; + + case WM_COMMAND: + // abort printing if the only button gets hit + fAbort = TRUE; + break; + + default: + return FALSE; + } + + return TRUE; + + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); +} // PrintDlgProc + + +/*+-------------------------------------------------------------------------+ + | PrintFile() | + | | + | Prints the contents of the edit control. | + | | + +-------------------------------------------------------------------------+*/ +VOID APIENTRY PrintFile(HWND hwnd) { + HDC hdc; + INT yExtPage; + CHAR sz[32]; + int cch; + WORD ich; + PSTR pch; + WORD iLine; + WORD nLinesEc; + WORD i; + HANDLE hT; + HWND hwndPDlg; + DWORD dy; + INT yExtSoFar; + WORD fError = TRUE; + HWND hwndEdit; + HFONT hFont, hOldFont; + + hwndEdit = (HWND)GetWindowLong(hwnd,GWL_HWNDEDIT); + + // Create the job title by loading the title string from STRINGTABLE + cch = LoadString (hInst, IDS_PRINTJOB, sz, sizeof(sz)); + szTitle = sz + cch; + cch += GetWindowText (hwnd, sz + cch, 32 - cch); + sz[31] = 0; + + // Initialize the printer + hdc = GetPrinterDC(FALSE); + if (!hdc) + goto getout5; + + SetMapMode(hdc, MM_TEXT); + SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT)); + + // Disable the main application window and create the Cancel dialog + EnableWindow (hwndFrame, FALSE); + + hwndPDlg = CreateDialog (hInst, IDD_PRINT, hwnd, (DLGPROC) PrintDlgProc); + + if (!hwndPDlg) + goto getout3; + + ShowWindow (hwndPDlg, SW_SHOW); + UpdateWindow (hwndPDlg); + + // Allow the app. to inform GDI of the escape function to call + if (Escape(hdc, SETABORTPROC, 0, (LPSTR)AbortProc, NULL) < 0) + goto getout1; + + // Initialize the document + if (Escape(hdc, STARTDOC, cch, (LPSTR)sz, NULL) < 0) + goto getout1; + + // Get the height of one line and the height of a page + { + SIZE tmp; + GetTextExtentPoint(hdc, "CC", 2, &tmp ); + dy = tmp.cy; + } + + yExtPage = GetDeviceCaps(hdc, VERTRES); + + // Get the lines in document and and a handle to the text buffer + iLine = 0; + yExtSoFar = 0; + nLinesEc = (WORD)SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L); + hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L); + + // While more lines print out the text + while (iLine < nLinesEc) { + if (yExtSoFar + (int) dy > yExtPage) { + // Reached the end of a page. Tell the device driver to eject a page + if (Escape(hdc, NEWFRAME, 0, NULL, NULL) < 0 || fAbort) + goto getout2; + yExtSoFar = 0; + } + + // Get the length and position of the line in the buffer and lock from that + // offset into the buffer. + ich = (WORD)SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L); + cch = (WORD)SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L); + pch = (PSTR)LocalLock(hT) + ich; + + // Print the line and unlock the text handle + TextOut (hdc, 0, yExtSoFar, (LPSTR)pch, cch); + LocalUnlock (hT); + + // Test and see if the Abort flag has been set. If yes, exit. + if (fAbort) + goto getout2; + + // Move down the page + yExtSoFar += dy; + iLine++; + } + + // Eject the last page. + if (Escape(hdc, NEWFRAME, 0, NULL, NULL) < 0) + goto getout2; + + // Complete the document. + if (Escape(hdc, ENDDOC, 0, NULL, NULL) < 0) { +getout2: + // Ran into a problem before NEWFRAME? Abort the document + Escape( hdc, ABORTDOC, 0, NULL, NULL); + } else + fError=FALSE; + +getout3: + // Close the cancel dialog and re-enable main app. window + EnableWindow (hwndFrame, TRUE); + DestroyWindow (hwndPDlg); + +getout1: + DeleteDC(hdc); + +getout5: +#ifdef WIN16 + // Get rid of dialog procedure instances + FreeProcInstance (lpfnPDlg); +#endif + +#ifdef WIN16 +getout4: + FreeProcInstance (lpfnAbort); +getout: +#endif + + // Error? make sure the user knows... + if (fError) + MPError (hwnd, MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPSTR)szTitle); + + return; + UNREFERENCED_PARAMETER(i); + +} // PrintFile + + +/*+-------------------------------------------------------------------------+ + | GetInitializationData() | + | | + | Gets DC initialization data from a printer driver supporting | + | ExtDeviceMode(). Called in response to the File/Printer setup menu | + | selection. | + | | + | This function allows the user to change the printer settings FOR | + | LOGVIEW ONLY. This allows LogView to print in a variety of settings | + | without messing up any othe applications. | + | | + +-------------------------------------------------------------------------+*/ +BOOL APIENTRY GetInitializationData( HWND hwnd ) { + LPSTR lpOld; + LPSTR lpNew; + FARPROC lpfn; + HANDLE hT,hDrv; + CHAR sz[32]; + int cb; + INT flag; + + // Pop up dialog for user and retain data in app buffer + flag = DM_PROMPT | DM_COPY; + + // Load the device driver and find the ExtDeviceMode() function + wsprintf (sz, "%s.drv", (LPSTR)szDriver); + if ((int)(hDrv = LoadLibrary (sz)) < 32) + return FALSE; + if (!(lpfn = (DLGPROC) GetProcAddress (hDrv, szExtDeviceMode))) + return FALSE; + + if (hInitData) { + // We have some old data... we want to modify the previously specified + // setup rather than starting with the default setup. + lpOld = (LPSTR)LocalLock(hInitData); + flag |= DM_MODIFY; + } + else + lpOld = NULL; + + // Get the number of bytes needed for the init data + cb = (*lpfn) (hwnd, hDrv, (LPDEVMODE)NULL, (LPSTR)szDevice, (LPSTR)szPort, (LPDEVMODE)NULL, (LPSTR)NULL, 0); + + // Grab some memory for the new data and lock it. + hT = LocalAlloc (LHND,cb); + if(!hT) { + MessageBox(hwnd, TEXT(" Not enough memory."), NULL, MB_OK | MB_ICONHAND); + LocalUnlock(hInitData); + LocalFree(hInitData); + FreeLibrary(hDrv); + return(FALSE); + } + + lpNew = (LPSTR)LocalLock (hT); + + // Post the device mode dialog. 0 flag iff user hits OK button + if ((*lpfn) (hwnd, hDrv, (LPDEVMODE)lpNew, (LPSTR)szDevice, (LPSTR)szPort, (LPDEVMODE)lpOld, (LPSTR)NULL, flag) == IDOK) + flag = 0; + + // Unlock the input structures + LocalUnlock (hT); + + if (hInitData) + LocalUnlock (hInitData); + + // If the user hit OK and everything worked, free the original init. data and + // retain the new one. Otherwise, toss the new buffer. + if (flag) + LocalFree (hT); + else { + if (hInitData) + LocalFree (hInitData); + + hInitData = hT; + } + + FreeLibrary(hDrv); + return (!flag); + +} // GetInitializationData diff --git a/private/nw/convert/logview/logview.c b/private/nw/convert/logview/logview.c new file mode 100644 index 000000000..a682edec0 --- /dev/null +++ b/private/nw/convert/logview/logview.c @@ -0,0 +1,767 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + LogView.C + +Abstract: + + +Author: + + Arthur Hanson (arth) 27-Jul-1993 + +Revision History: + +--*/ + +#include "LogView.h" +#include +#include +//#include +//#include +#include + +// global variables used in this module or among more than one module +HANDLE hInst; +HANDLE hAccel; +HWND hwndFrame = NULL; +HWND hwndMDIClient = NULL; +HWND hwndActive = NULL; +HWND hwndActiveEdit = NULL; +HWND hDlgFind = NULL; +LPSTR lpMenu = IDLOGVIEW; +TCHAR szAppName[] = "LogView"; + +FINDREPLACE FR; +PRINTDLG PD; +UINT wFRMsg; +UINT wHlpMsg; +BOOL fReverse = FALSE; // Flag for direction of search +TCHAR szSearch[CCHKEYMAX]; // Search String + +HANDLE hStdCursor; // handle to arrow or beam cursor +HANDLE hWaitCursor; // handle to hour glass cursor + +void FAR Search (TCHAR * szKey); + + +// Forward declarations of helper functions in this module +VOID NEAR PASCAL InitializeMenu (HANDLE); +VOID NEAR PASCAL CommandHandler (HWND, UINT, LONG); +LPSTR GetCmdLine( VOID ); +BOOL CenterWindow( HWND hwndChild, HWND hwndParent ); + +#define HELP_FILE TEXT("logview.hlp") + +///////////////////////////////////////////////////////////////////////// +int PASCAL +WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) + +/*++ + +Routine Description: + + Creates the "frame" window, does some initialization and enters the + message loop. + +Arguments: + + +Return Value: + + +--*/ + +{ + MSG msg; + + hInst = hInstance; + + // If this is the first instance of the app. register window classes + if (!hPrevInstance){ + if (!InitializeApplication ()) + return 0; + } + + lpCmdLine = GetCmdLine(); + + // Create the frame and do other initialization + if (!InitializeInstance (lpCmdLine, nCmdShow)) + return 0; + + while (GetMessage (&msg, NULL, 0, 0)){ + // If a keyboard message is for the MDI , let the MDI client take care of it. + // Otherwise, check to see if it's a normal accelerator key (like F3 = find next). + // Otherwise, just handle the message as usual. + if (!hDlgFind || !IsDialogMessage(hDlgFind, &msg)) { + if ( !TranslateMDISysAccel (hwndMDIClient, &msg) && + !TranslateAccelerator (hwndFrame, hAccel, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + } + + return 0; + +} // WinMain + + +///////////////////////////////////////////////////////////////////////// +LONG APIENTRY +MPFrameWndProc ( + HWND hwnd, + UINT msg, + UINT wParam, + LONG lParam + ) + +/*++ + +Routine Description: + + The window function for the "frame" window, which controls the menu + and encompasses all the MDI child windows. + +Arguments: + + +Return Value: + + +--*/ + +{ + LPFINDREPLACE lpfr; + DWORD dwFlags; + + switch (msg) { + case WM_CREATE: { + + CLIENTCREATESTRUCT ccs; + HDC hdc; + + // Find window menu where children will be listed + ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd), WINDOWMENU); + ccs.idFirstChild = IDM_WINDOWCHILD; + + // Create the MDI client filling the client area + hwndMDIClient = CreateWindow ("mdiclient", NULL, + WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, + 0, 0, 0, 0, hwnd, (HMENU) 0xCAC, hInst, (LPSTR) &ccs); + + ShowWindow (hwndMDIClient,SW_SHOW); + + // Check if printer can be initialized + if (hdc = GetPrinterDC (TRUE)) { + DeleteDC (hdc); + } + + break; + } + + case WM_INITMENU: + // Set up the menu state + InitializeMenu ((HMENU)wParam); + break; + + case WM_WININICHANGE: + case WM_DEVMODECHANGE:{ + + // If control panel changes default printer characteristics, reinitialize our + // printer information... + HDC hdc; + + if (hdc = GetPrinterDC (TRUE)) + DeleteDC (hdc); + + break; + } + + case WM_COMMAND: + // Direct all menu selection or accelerator commands to another function + CommandHandler(hwnd, wParam, lParam); + break; + + case WM_CLOSE: + DestroyWindow (hwnd); + break; + + case WM_DESTROY: + PostQuitMessage (0); + break; + + default: + if (msg == wFRMsg) + { + lpfr = (LPFINDREPLACE)lParam; + dwFlags = lpfr->Flags; + + fReverse = (dwFlags & FR_DOWN ? FALSE : TRUE); + fCase = (dwFlags & FR_MATCHCASE ? TRUE : FALSE); + + if (dwFlags & FR_FINDNEXT) + Search (szSearch); + else if (dwFlags & FR_DIALOGTERM) + hDlgFind = NULL; /* invalidate modeless window handle */ + break; + } + + // use DefFrameProc() instead of DefWindowProc() since there are things + // that have to be handled differently because of MDI + return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam); + } + + return 0; + +} // MPFrameWndProc + + +///////////////////////////////////////////////////////////////////////// +LONG APIENTRY +MPMDIChildWndProc ( + HWND hwnd, + UINT msg, + UINT wParam, + LONG lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + HWND hwndEdit; + HFONT hFont; + LRESULT ret; + + switch (msg) { + case WM_CREATE: + hwndEdit = CreateWindow ("edit", NULL, + WS_CHILD | WS_HSCROLL | WS_MAXIMIZE | WS_VISIBLE | + WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL | + ES_MULTILINE | ES_READONLY | ES_NOHIDESEL, + 0, 0, 0, 0, + hwnd, (HMENU) ID_EDIT, hInst, NULL); + + // Remember the window handle and initialize some window attributes + SetWindowLong (hwnd, GWL_HWNDEDIT, (LONG) hwndEdit); + SetWindowWord (hwnd, GWW_CHANGED, FALSE); + SetWindowWord (hwnd, GWL_WORDWRAP, FALSE); + SetWindowWord (hwnd, GWW_UNTITLED, TRUE); + + hFont = GetStockObject(SYSTEM_FIXED_FONT); + ret = SendMessage(hwndEdit, WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG((WORD) TRUE, 0)); + + SetFocus (hwndEdit); + break; + + case WM_MDIACTIVATE: + // If we're activating this child, remember it + if (GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wParam, lParam)) { + hwndActive = hwnd; + hwndActiveEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT); + } + else { + hwndActive = NULL; + hwndActiveEdit = NULL; + } + break; + + case WM_CLOSE: + goto CallDCP; + + case WM_SIZE:{ + RECT rc; + + // On creation or resize, size the edit control. + hwndEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT); + GetClientRect (hwnd, &rc); + MoveWindow (hwndEdit, + rc.left, + rc.top, + rc.right-rc.left, + rc.bottom-rc.top, + TRUE); + goto CallDCP; + } + + case WM_SETFOCUS: + SetFocus ((HWND)GetWindowLong (hwnd, GWL_HWNDEDIT)); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)){ + case ID_EDIT: + switch (GET_WM_COMMAND_CMD(wParam, lParam)) { + + case EN_ERRSPACE: + // If the control is out of space, beep + MessageBeep (0); + break; + + default: + goto CallDCP; + } + break; + + default: + goto CallDCP; + } + break; + + default: +CallDCP: + return DefMDIChildProc (hwnd, msg, wParam, lParam); + } + return FALSE; + +} // MPMDIChildWndProc + + +///////////////////////////////////////////////////////////////////////// +VOID NEAR PASCAL +InitializeMenu ( + register HANDLE hmenu + ) + +/*++ + +Routine Description: + + Sets up greying, enabling and checking of main menu items. + +Arguments: + + +Return Value: + + +--*/ + +{ + WORD status; + WORD i; + INT j; + + // Is there any active child to talk to? + if (hwndActiveEdit) { + + // Set the word wrap state for the window + if ((WORD) SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 0, 0))) + status = MF_CHECKED; + else + status = MF_UNCHECKED; + + CheckMenuItem (hmenu, IDM_EDITWRAP, status); + + // Enable search menu items only if there is a search string + if (*szSearch) + status = MF_ENABLED; + else + status = MF_GRAYED; + + EnableMenuItem (hmenu, IDM_SEARCHNEXT, status); + EnableMenuItem (hmenu, IDM_SEARCHPREV, status); + + // Enable File/Print only if a printer is available + status = (WORD) (iPrinter ? MF_ENABLED : MF_GRAYED); + EnableMenuItem (hmenu, IDM_FILEPRINT, status); + + // select all and wrap toggle always enabled + status = MF_ENABLED; + EnableMenuItem(hmenu, IDM_EDITSELECT, status); + EnableMenuItem(hmenu, IDM_EDITWRAP, status); + EnableMenuItem(hmenu, IDM_SEARCHFIND, status); + } else { + // There are no active child windows + status = MF_GRAYED; + + // No active window, so disable everything + for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i++) + EnableMenuItem (hmenu, i, status); + + CheckMenuItem (hmenu, IDM_EDITWRAP, MF_UNCHECKED); + + for (i = IDM_SEARCHFIRST; i <= IDM_SEARCHLAST; i++) + EnableMenuItem (hmenu, i, status); + + EnableMenuItem (hmenu, IDM_FILEPRINT, status); + + } + + // The following menu items are enabled if there is an active window + EnableMenuItem (hmenu, IDM_WINDOWTILE, status); + EnableMenuItem (hmenu, IDM_WINDOWCASCADE, status); + EnableMenuItem (hmenu, IDM_WINDOWICONS, status); + EnableMenuItem (hmenu, IDM_WINDOWCLOSEALL, status); + + // Allow printer setup only if printer driver supports device initialization + if (iPrinter < 2) + status = MF_GRAYED; + + EnableMenuItem ( hmenu, IDM_FILESETUP, status); + UNREFERENCED_PARAMETER(j); + +} // InitializeMenu + + +///////////////////////////////////////////////////////////////////////// +VOID NEAR PASCAL +CloseAllChildren () + +/*++ + +Routine Description: + + Destroys all MDI child windows. + +Arguments: + + +Return Value: + + +--*/ + +{ + register HWND hwndT; + + // hide the MDI client window to avoid multiple repaints + ShowWindow(hwndMDIClient,SW_HIDE); + + // As long as the MDI client has a child, destroy it + while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){ + + // Skip the icon title windows + while (hwndT && GetWindow (hwndT, GW_OWNER)) + hwndT = GetWindow (hwndT, GW_HWNDNEXT); + + if (!hwndT) + break; + + SendMessage (hwndMDIClient, WM_MDIDESTROY, (UINT)hwndT, 0L); + } + +} // CloseAllChildren + + +///////////////////////////////////////////////////////////////////////// +VOID NEAR PASCAL +CommandHandler ( + HWND hwnd, + UINT wParam, + LONG lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DLGPROC lpfnDlg; + + switch (LOWORD(wParam)){ + case IDM_FILENEW: + // Add a new, empty MDI child + AddFile (NULL); + break; + + case IDM_FILEOPEN: + MyReadFile (hwnd); + break; + + case IDM_FILEPRINT: + // Print the active child MDI + PrintFile (hwndActive); + break; + + case IDM_FILESETUP: + // Set up the printer environment for this app + GetInitializationData (hwnd); + break; + + case IDM_FILEMENU: { + // lengthen / shorten the size of the MDI menu + HMENU hMenu; + HMENU hWindowMenu; + INT i; + + if (lpMenu == IDLOGVIEW) { + lpMenu = IDLOGVIEW2; + i = SHORTMENU; + } + else { + lpMenu = IDLOGVIEW; + i = WINDOWMENU; + } + + hMenu = LoadMenu (hInst, lpMenu); + hWindowMenu = GetSubMenu (hMenu, i); + + // Set the new menu + hMenu = (HMENU)SendMessage (hwndMDIClient, + WM_MDISETMENU, + (UINT)hMenu, + (LONG)hWindowMenu); + + DestroyMenu (hMenu); + DrawMenuBar (hwndFrame); + break; + } + + case IDM_FILEEXIT: + // Close LogView + SendMessage (hwnd, WM_CLOSE, 0, 0L); + break; + + case IDM_HELPABOUT: + // Just let the shell display the about box... + ShellAbout(hwnd, szAppName, szAppName, LoadIcon(hInst, IDLOGVIEW)); + break; + + // The following are edit commands. Pass these off to the active child'd edit + // control window. + case IDM_EDITWRAP: + SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 1, 0)); + break; + + case IDM_SEARCHPREV: + if (szSearch[0]) { + fReverse = TRUE; + Search(szSearch); + break; + } + // else fall through and bring up find dialog + + case IDM_SEARCHNEXT: + if (szSearch[0]) { + fReverse = FALSE; + Search(szSearch); + break; + } + // else fall through and bring up find dialog + + case IDM_SEARCHFIND: + if (hDlgFind) + SetFocus(hDlgFind); + else { + FR.lpstrFindWhat = szSearch; + FR.wFindWhatLen = CCHKEYMAX; + hDlgFind = FindText((LPFINDREPLACE)&FR); + } + + break; + + // The following are window commands - these are handled by the MDI Client. + case IDM_WINDOWTILE: + // Tile MDI windows + SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L); + break; + + case IDM_WINDOWCASCADE: + // Cascade MDI windows + SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L); + break; + + case IDM_WINDOWICONS: + // Auto - arrange MDI icons + SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L); + break; + + case IDM_WINDOWCLOSEALL: + CloseAllChildren(); + + // Show the window since CloseAllChilren() hides the window for fewer repaints + ShowWindow( hwndMDIClient, SW_SHOW); + break; + + case ID_HELP_CONT: + WinHelp(hwnd, HELP_FILE, HELP_CONTENTS, 0L); + break; + + case ID_HELP_INDEX: + WinHelp(hwnd, HELP_FILE, HELP_PARTIALKEY, (DWORD) TEXT("\0")); + break; + + case ID_HELP_USING: + WinHelp(hwnd, HELP_FILE, HELP_HELPONHELP, (DWORD) TEXT("\0")); + break; + + default: + // This is essential, since there are frame WM_COMMANDS generated by the MDI + // system for activating child windows via the window menu. + DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND, wParam, lParam); + } + +} // CommandHandler + + +///////////////////////////////////////////////////////////////////////// +SHORT +MPError( + HWND hwnd, + WORD bFlags, + WORD id, + char *psz + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + CHAR sz[160]; + CHAR szFmt[128]; + + LoadString (hInst, id, szFmt, sizeof (szFmt)); + sprintf (sz, szFmt, psz ); + LoadString (hInst, (WORD)IDS_APPNAME, (LPSTR)szFmt, sizeof (szFmt)); + return( (SHORT)MessageBox (hwndFrame, sz, szFmt, bFlags)); + + UNREFERENCED_PARAMETER(hwnd); +} // MPError + + +///////////////////////////////////////////////////////////////////////// +LPSTR +GetCmdLine( + VOID + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPSTR lpCmdLine, lpT; + + lpCmdLine = GetCommandLine(); + + // on Win32, lpCmdLine's first string includes its own name, remove this + if (*lpCmdLine) { + lpT = strchr(lpCmdLine, ' '); // skip self name + + if (lpT) { + lpCmdLine = lpT; + + while (*lpCmdLine == ' ') { + lpCmdLine++; // skip spaces to end or first cmd + } + + } else { + lpCmdLine += strlen(lpCmdLine); // point to NULL + } + } + return(lpCmdLine); + +} // GetCmdLine + + +#define CY_SHADOW 4 +#define CX_SHADOW 4 + +///////////////////////////////////////////////////////////////////////// +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 diff --git a/private/nw/convert/logview/logview.dlg b/private/nw/convert/logview/logview.dlg new file mode 100644 index 000000000..961272f7d --- /dev/null +++ b/private/nw/convert/logview/logview.dlg @@ -0,0 +1,51 @@ + +ABOUTBOX DIALOG DISCARDABLE 80, 40, 256, 94 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About LogView" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "LogView", -1, 6, 6, 0, 0 + CTEXT "Logging Tool for NetWare in Windows NT Server",IDC_STATIC,45, + 5,200,8,NOT WS_GROUP + CTEXT "LogView Version 3.51",IDC_STATIC,45,15,200,8,NOT WS_GROUP + CTEXT "Copyright(c) Microsoft Corporation 1993-1996.",IDC_STATIC,45,25,200,8 + CTEXT "All Rights Reserved.",IDC_STATIC,45,35,200,8 + + CONTROL "",IDC_STATIC,"Static",SS_BLACKRECT,45,45,200,1 + LTEXT "Physical Memory:",IDC_STATIC,56,55,63,8,NOT WS_GROUP + LTEXT "(Avail mem)",IDC_PHYSICAL_MEM,127,55,129,8,NOT WS_GROUP + LTEXT "Disk Space:",IDC_STATIC,56,65,49,8,NOT WS_GROUP + LTEXT "(Disk space)",IDC_DISK_SPACE,127,65,128,8,NOT WS_GROUP + + DEFPUSHBUTTON "OK",IDOK,108,77,40,14 + +END + + +// "Search/Find..." dialog box + +IDD_FIND DIALOG LOADONCALL MOVEABLE DISCARDABLE 18, 13, 167, 69 +FONT 8, "MS Shell Dlg" +CAPTION "Find" +STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU +BEGIN + CONTROL "&Find:", 100, "static", SS_RIGHT | WS_CHILD, 6, 12, 31, 10 + CONTROL "", IDD_SEARCH, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD, 43, 11, 114, 12 + CONTROL "&Case Sensitive", IDD_CASE, "button", BS_CHECKBOX | WS_TABSTOP | WS_CHILD, 19, 28, 137, 12 + CONTROL "&Next", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 11, 48, 45, 14 + CONTROL "&Previous", IDD_PREV, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 63, 48, 45, 14 + CONTROL "C&ancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 116, 48, 43, 14 +END + + +// Cancel dialog for printing + +IDD_PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 90, 64 +FONT 8, "MS Shell Dlg" +STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU +CAPTION "Print" +BEGIN + CTEXT "Now Printing", -1, 0, 8, 90, 8 + CTEXT "", IDD_PRINTTITLE, 0, 18, 90, 8, SS_NOPREFIX + DEFPUSHBUTTON "Cancel" IDOK, 29, 44, 32, 14 +END diff --git a/private/nw/convert/logview/logview.h b/private/nw/convert/logview/logview.h new file mode 100644 index 000000000..69734edff --- /dev/null +++ b/private/nw/convert/logview/logview.h @@ -0,0 +1,214 @@ + +#include "windows.h" + +#ifndef WIN16 +#ifndef WIN32 + #define WIN32 1 // placed because RC can't pass in C_DEFINES +#endif + #include +#endif + +#define CCHKEYMAX 32 // max characters in search string + +#define GET_EM_SETSEL_MPS(iStart, iEnd) (UINT)(iStart), (LONG)(iEnd) +#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) +#define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) +#define GET_WM_COMMAND_MPS(id, hwnd, cmd) (UINT)MAKELONG(id, cmd), (LONG)(hwnd) +#define GET_EM_SETSEL_MPS(iStart, iEnd) (UINT)(iStart), (LONG)(iEnd) +#define GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wp, lp) (lp == (LONG)hwnd) + +#define WINDOWMENU 2 // position of window menu +#define SHORTMENU 2 // position of short version window menu + +#define DEFFILESEARCH (LPSTR) "*.LOG" + +#ifdef RC_INVOKED +#define ID(id) id +#else +#define ID(id) MAKEINTRESOURCE(id) +#endif + +// edit control identifier +#define ID_EDIT 0xCAC + +// resource ID's +#define IDLOGVIEW ID(1) +#define IDLOGVIEW2 ID(3) +#define IDNOTE ID(2) + +// Window word values for child windows +#define GWL_HWNDEDIT 0 +#define GWW_CHANGED 4 +#define GWL_WORDWRAP 6 +#define GWW_UNTITLED 10 +#define CBWNDEXTRA 12 + +// menu ID's +#define IDM_FILENEW 1001 +#define IDM_FILEOPEN 1002 +#define ID_HELP_INDEX 1003 +#define ID_HELP_USING 1004 +#define ID_HELP_CONT 1005 +#define IDM_FILEPRINT 1006 +#define IDM_FILEEXIT 1007 +#define IDM_FILEABOUT 1008 +#define IDM_FILESETUP 1009 +#define IDM_FILEMENU 1010 + +#define IDM_EDITUNDO 2001 +#define IDM_EDITCUT 2002 +#define IDM_EDITCOPY 2003 +#define IDM_EDITPASTE 2004 +#define IDM_EDITCLEAR 2005 +#define IDM_EDITSELECT 2006 +#define IDM_EDITTIME 2007 +#define IDM_EDITWRAP 2008 +#define IDM_EDITFONT 2009 +#define IDM_EDITFIRST IDM_EDITUNDO +#define IDM_EDITLAST IDM_EDITFONT + +#define IDM_SEARCHFIND 3001 +#define IDM_SEARCHNEXT 3002 +#define IDM_SEARCHPREV 3003 +#define IDM_SEARCHFIRST IDM_SEARCHFIND +#define IDM_SEARCHLAST IDM_SEARCHPREV + +#define IDM_WINDOWTILE 4001 +#define IDM_WINDOWCASCADE 4002 +#define IDM_WINDOWCLOSEALL 4003 +#define IDM_WINDOWICONS 4004 + +#define IDM_WINDOWCHILD 4100 + +#define IDM_HELPHELP 5001 +#define IDM_HELPABOUT 5002 +#define IDM_HELPSPOT 5003 + +#define IDD_FILEOPEN ID(200) +#define IDD_FILENAME 201 +#define IDD_FILES 202 +#define IDD_PATH 203 +#define IDD_DIRS 204 + +// dialog ids +#define IDD_ABOUT ID(300) + +#define IDD_FIND ID(400) +#define IDD_SEARCH 401 +#define IDD_PREV 402 +#define IDD_NEXT IDOK +#define IDD_CASE 403 + +#define IDD_SAVEAS ID(500) +#define IDD_SAVEFROM 501 +#define IDD_SAVETO 502 + +#define IDD_PRINT ID(600) +#define IDD_PRINTDEVICE 601 +#define IDD_PRINTPORT 602 +#define IDD_PRINTTITLE 603 + +#define IDD_FONT ID(700) +#define IDD_FACES 701 +#define IDD_SIZES 702 +#define IDD_BOLD 703 +#define IDD_ITALIC 704 +#define IDD_FONTTITLE 705 + +// +------------------------------------------------------------------------+ +// About Box +// +------------------------------------------------------------------------+ +#define IDC_AVAIL_MEM 101 +#define IDC_PHYSICAL_MEM 101 +#define IDC_LICENSEE_COMPANY 104 +#define IDC_LICENSEE_NAME 105 +#define IDD_SPLASH 105 +#define IDC_MATH_COPR 106 +#define IDC_DISK_SPACE 107 +#define IDC_BIGICON 1001 + +// strings +#define IDS_CANTOPEN 1 +#define IDS_CANTREAD 2 +#define IDS_CANTCREATE 3 +#define IDS_CANTWRITE 4 +#define IDS_ILLFNM 5 +#define IDS_ADDEXT 6 +#define IDS_CLOSESAVE 7 +#define IDS_CANTFIND 8 +#define IDS_HELPNOTAVAIL 9 +#define IDS_CANTFINDSTR 10 + +#define IDS_CLIENTTITLE 16 +#define IDS_UNTITLED 17 +#define IDS_APPNAME 18 + +#define IDS_PRINTJOB 24 +#define IDS_PRINTERROR 25 + +#define IDS_DISK_SPACE_UNAVAIL 26 +#define IDS_DISK_SPACE 27 +#define IDS_MATH_COPR_NOTPRESENT 28 +#define IDS_MATH_COPR_PRESENT 29 +#define IDS_AVAIL_MEM 30 +#define IDS_PHYSICAL_MEM 31 + +#define IDS_OPENTEXT 32 +#define IDS_OPENFILTER 33 +#define IDS_DEFEXT 34 + +#define IDC_STATIC -1 + + +// attribute flags for DlgDirList +#define ATTR_DIRS 0xC010 // find drives and directories +#define ATTR_FILES 0x0000 // find ordinary files +#define PROP_FILENAME szPropertyName // name of property for dialog + + +// External variable declarations +extern HANDLE hInst; // application instance handle +extern HANDLE hAccel; // resource handle of accelerators +extern HWND hwndFrame; // main window handle +extern HWND hwndMDIClient; // handle of MDI Client window +extern HWND hwndActive; // handle of current active MDI child +extern HWND hwndActiveEdit; // handle of edit control in active child +extern LONG styleDefault; // default child creation state +extern CHAR szChild[]; // class of child +extern CHAR szSearch[]; // search string +extern CHAR *szDriver; // name of printer driver +extern CHAR szPropertyName[]; // filename property for dialog box +extern INT iPrinter; // level of printing capability +extern BOOL fCase; // searches case sensitive +extern WORD cFonts; // number of fonts enumerated + +extern FINDREPLACE FR; +extern UINT wHlpMsg; +extern UINT wFRMsg; +extern BOOL fReverse; + +extern HANDLE hStdCursor, hWaitCursor; + +// externally declared functions +extern BOOL APIENTRY InitializeApplication(VOID); +extern BOOL APIENTRY InitializeInstance(LPSTR,INT); +extern BOOL APIENTRY AboutDlgProc(HWND,UINT,UINT,LONG); +extern HWND APIENTRY AddFile(CHAR *); +extern VOID APIENTRY MyReadFile(HWND); +extern INT APIENTRY LoadFile(HWND, CHAR *); +extern VOID APIENTRY PrintFile(HWND); +extern BOOL APIENTRY GetInitializationData(HWND); +extern SHORT MPError(HWND,WORD,WORD, char *); +extern VOID APIENTRY Find(VOID); +extern VOID APIENTRY FindNext(VOID); +extern VOID APIENTRY FindPrev(VOID); +extern LONG APIENTRY MPFrameWndProc(HWND,UINT,UINT,LONG); +extern LONG APIENTRY MPMDIChildWndProc(HWND,UINT,UINT,LONG); +extern HDC APIENTRY GetPrinterDC(BOOL); +extern VOID NEAR PASCAL SetSaveFrom (HWND, PSTR); +extern BOOL NEAR PASCAL RealSlowCompare (PSTR, PSTR); +extern VOID APIENTRY FindPrev (VOID); +extern VOID APIENTRY FindNext (VOID); +extern BOOL NEAR PASCAL IsWild (PSTR); +extern VOID NEAR PASCAL SelectFile (HWND); +extern VOID NEAR PASCAL Local_FindText ( INT ); diff --git a/private/nw/convert/logview/logview.rc b/private/nw/convert/logview/logview.rc new file mode 100644 index 000000000..16e69a74e --- /dev/null +++ b/private/nw/convert/logview/logview.rc @@ -0,0 +1,111 @@ + +#include "logview.h" +#include "version.h" + +IDLOGVIEW ICON FV300.ico // main icon +LogView ICON FV300.ICO +IDNOTE ICON note300.ico // icon for child windows + +// frame window menu + +IDLOGVIEW MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open...", IDM_FILEOPEN + MENUITEM SEPARATOR + MENUITEM "&Print", IDM_FILEPRINT + MENUITEM "Printer Se&tup...", IDM_FILESETUP + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILEEXIT + END + POPUP "&Search" + BEGIN + MENUITEM "&Find...", IDM_SEARCHFIND + MENUITEM "&Next\tF3", IDM_SEARCHNEXT + MENUITEM "&Previous\tF4", IDM_SEARCHPREV + END + POPUP "&Window" + BEGIN + MENUITEM "&Tile", IDM_WINDOWTILE + MENUITEM "&Cascade", IDM_WINDOWCASCADE + MENUITEM "Arrange &Icons", IDM_WINDOWICONS + MENUITEM "Close &All", IDM_WINDOWCLOSEALL + END + POPUP "&Help" + { + MENUITEM "&Contents", ID_HELP_CONT + MENUITEM "&Search for Help on...", ID_HELP_INDEX + MENUITEM "&How to Use Help", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "&About LogView...", IDM_HELPABOUT + } +END + +// short frame window menu +IDLOGVIEW2 MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open...", IDM_FILEOPEN + MENUITEM SEPARATOR + MENUITEM "&Print...", IDM_FILEPRINT + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILEEXIT + MENUITEM SEPARATOR + MENUITEM "&About logview...", IDM_HELPABOUT + END + POPUP "&Window" + BEGIN + MENUITEM "&Arrange", IDM_WINDOWTILE + END +END + +// frame menu accelerators + +IDLOGVIEW ACCELERATORS +BEGIN + VK_INSERT, IDM_EDITCOPY, VIRTKEY, CONTROL + VK_INSERT, IDM_EDITPASTE, VIRTKEY, SHIFT + VK_DELETE, IDM_EDITCUT, VIRTKEY, SHIFT + VK_BACK, IDM_EDITUNDO, VIRTKEY, ALT + VK_F5, IDM_EDITTIME, VIRTKEY + VK_F3, IDM_SEARCHNEXT, VIRTKEY + VK_F4, IDM_SEARCHPREV, VIRTKEY + VK_F1, IDM_HELPHELP, VIRTKEY + VK_F1, IDM_HELPSPOT, VIRTKEY, SHIFT +END + + + +STRINGTABLE +BEGIN + +IDS_CANTOPEN "Can't open the file '%s'" +IDS_CANTREAD "Can't read the file '%s'" +IDS_CANTCREATE "Can't create the file '%s'" +IDS_CANTWRITE "Can't write the file '%s'" +IDS_ADDEXT ".TXT" +IDS_ILLFNM "Invalid filename: '%s'" +IDS_CLOSESAVE "%s has been changed. Save file before closing?" +IDS_CANTFIND "Can't find '%s'" +IDS_HELPNOTAVAIL "Can't load Windows Help application" +IDS_CLIENTTITLE "LogView App, Version 3.51" +IDS_UNTITLED "Untitled" +IDS_PRINTJOB "LogView - " +IDS_PRINTERROR "Cannot print %s!" +IDS_APPNAME "LogView" +IDS_CANTFINDSTR "Can't find string" + + IDS_DISK_SPACE_UNAVAIL "Unavailable" + IDS_DISK_SPACE "%lu KB Free" + IDS_MATH_COPR_NOTPRESENT "Not present" + IDS_MATH_COPR_PRESENT "Present" + IDS_PHYSICAL_MEM "%lu KB Free" + +IDS_OPENTEXT "Open TextFiles" +IDS_OPENFILTER "Log Files(*.LOG)\0*.LOG\0" +IDS_DEFEXT "LOG" +END + +#include "logview.dlg" diff --git a/private/nw/convert/logview/makefile b/private/nw/convert/logview/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/nw/convert/logview/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/nw/convert/logview/note300.ico b/private/nw/convert/logview/note300.ico new file mode 100644 index 000000000..0446c5579 Binary files /dev/null and b/private/nw/convert/logview/note300.ico differ diff --git a/private/nw/convert/logview/sources b/private/nw/convert/logview/sources new file mode 100644 index 000000000..46f19230d --- /dev/null +++ b/private/nw/convert/logview/sources @@ -0,0 +1,23 @@ +TARGETNAME=logview +TARGETPATH=obj +TARGETTYPE=PROGRAM + +TARGETLIBS=\ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib + +C_DEFINES=-DWIN32 -DWINVER=0x0400 + +SUBSYSTEM_VERSION=4.00 + +SOURCES=\ + LOGVIEW.RC \ + LOGVIEW.C \ + FVFILE.C \ + FVFIND.C \ + FVINIT.C \ + FVOPEN.C \ + FVPRINT.C + +UMTYPE=windows +UMENTRY=winmain diff --git a/private/nw/convert/logview/version.h b/private/nw/convert/logview/version.h new file mode 100644 index 000000000..ba9fb71b6 --- /dev/null +++ b/private/nw/convert/logview/version.h @@ -0,0 +1,52 @@ +/* +** Template for version resources. Place this in your .rc file, +** editing the values for VER_FILETYPE, VER_FILESUBTYPE, +** VER_FILEDESCRIPTION_STR and VER_INTERNALNAME_STR as needed. +** See winver.h for possible values. +** +** Ntverp.h defines several global values that don't need to be +** changed except for official releases such as betas, sdk updates, etc. +** +** Common.ver has the actual version resource structure that all these +** #defines eventually initialize. +*/ + +/* #include needed if this will be the .rc file */ + +#include + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR + * and VER_INTERNALNAME_STR must be defined before including COMMON.VER + * The strings don't need a '\0', since common.ver has them. + */ +#define VER_FILETYPE VFT_APP +/* possible values: VFT_UNKNOWN + VFT_APP + VFT_DLL + VFT_DRV + VFT_FONT + VFT_VXD + VFT_STATIC_LIB +*/ +#define VER_FILESUBTYPE VFT2_UNKNOWN +/* possible values VFT2_UNKNOWN + VFT2_DRV_PRINTER + VFT2_DRV_KEYBOARD + VFT2_DRV_LANGUAGE + VFT2_DRV_DISPLAY + VFT2_DRV_MOUSE + VFT2_DRV_NETWORK + VFT2_DRV_SYSTEM + VFT2_DRV_INSTALLABLE + VFT2_DRV_SOUND + VFT2_DRV_COMM +*/ +#define VER_FILEDESCRIPTION_STR "Migration Tool for NetWare Log File Viewer" +#define VER_INTERNALNAME_STR "LogView" +#define VER_ORIGINALFILENAME_STR "LOGVIEW.EXE" + +#include "common.ver" diff --git a/private/nw/convert/nwconv/aboutbox.c b/private/nw/convert/nwconv/aboutbox.c new file mode 100644 index 000000000..d44a898d4 --- /dev/null +++ b/private/nw/convert/nwconv/aboutbox.c @@ -0,0 +1,39 @@ +/* + +-------------------------------------------------------------------------+ + | About Box Routine | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [AboutBox.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993] | + | Last Update : [Jun 18, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | About box code, nuff said. | + | | + | | + | History: | + | arth Jun 18, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "globals.h" +#include + +extern TCHAR szAppName[]; + +/*+-------------------------------------------------------------------------+ + | AboutBox_Do() + | + +-------------------------------------------------------------------------+*/ +void AboutBox_Do(HWND hDlg) { + + ShellAbout(hDlg, szAppName, szAppName, LoadIcon(hInst, szAppName)); + +} // AboutBox_Do diff --git a/private/nw/convert/nwconv/columnlb.c b/private/nw/convert/nwconv/columnlb.c new file mode 100644 index 000000000..468595ba1 --- /dev/null +++ b/private/nw/convert/nwconv/columnlb.c @@ -0,0 +1,2986 @@ +// ================================================================================================== +// COPYRIGHT 1992,1993 MICROSOFT CORP ALL RIGHTS RESERVED +// ================================================================================================== +// +// - Custom control to display Columns/Titles above a list box +// +// TERMINOLOGY: +// PHYSICAL COLUMNS: The index of the original columns in their original order +// VIRtUAL COLUMNS: The index of the column as the display is currently showing it based on +// the current order. +// +// History: +// ------- +// RickD 04/10/92 created TitleListBox +// Tom Laird-McConnell 12/30/92 Ported to Win32, added to BH project +// Tom Laird-McConnell 05/01/93 gutted titlelist and used as base for complete rewrite as ColumnLB +// Tom Laird-McConnell 08/18/93 Added tabbed-delimited string support +// Arth 03/24/94 Added Unicode support +// ================================================================================================== +#define STRICT 1 +#include "switches.h" + +#include +#include + +#include +#include + +// #include + +#include "columnlb.h" +#include "vlist.h" + +#include "utils.h" +#include "debug.h" +#include "mem.h" + + +//#define DEBUG_HSCROLL 1 + +#define WHITESPACE 8 + +#define IDL_COLUMNLISTBOX (CLB_BASE + 1) +#define IDL_COLUMNTITLELISTBOX (CLB_BASE + 2) + +#define LB16_ADDSTRING (WM_USER+1) +#define LB16_INSERTSTRING (WM_USER+2) + +typedef struct _COLRECORD +{ + DWORD itemData; + LPTSTR pString[]; +} COLRECORD; +typedef COLRECORD *LPCOLRECORD; + +// ------------------------------------------------------------------------------------- +// +// window procs +// +LRESULT CALLBACK ColumnLBClass_ListBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK ColumnLBClass_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// +// system message handlers +// +BOOL ColumnLBClass_OnNCCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct); +void ColumnLBClass_OnNCDestroy(HWND hwnd); +void ColumnLBClass_OnDestroy(HWND hwnd); +void ColumnLBClass_OnPaint(HWND hwnd); +void ColumnLBClass_OnSize(HWND hwnd, UINT state, int cx, int cy); +void ColumnLBClass_OnSetFont(HWND hwnd, HFONT hfont, BOOL fRedraw); +LRESULT ColumnLBClass_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos); +void ColumnLBClass_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem); +void ColumnLBClass_OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpMeasureItem); +void ColumnLBClass_OnDeleteItem(HWND hwnd, const DELETEITEMSTRUCT *lpDeleteItem); +int ColumnLBClass_OnCharToItem(HWND hwnd, UINT ch, HWND hwndListbox, int iCaret); + +// +// WM_USER message handlers +// +BYTE ColumnLBClass_OnNumberCols(HWND hwnd, BYTE NewNumberCols, BOOL fSetColumns); +int ColumnLBClass_OnColWidth(HWND hwnd, BYTE Column, int NewWidth, BOOL fSetWidth); +LPTSTR ColumnLBClass_OnColTitle(HWND hwnd, BYTE Column, LPTSTR lpTitle, BOOL fSetTitle); +BYTE ColumnLBClass_OnSortCol(HWND hwnd, BYTE NewSortCol, BOOL fSetSortCol); +LPBYTE ColumnLBClass_OnColOrder(HWND hwnd, LPBYTE NewColOrder, BOOL fSetOrder); +LPINT ColumnLBClass_OnColOffsets(HWND hwnd, LPINT NewOffsetTable, BOOL fSetOffsets); +LRESULT ColumnLBClass_OnAutoWidth(HWND hwnd, BYTE ColumnToCompute); + + +// +// mouse movement messages +// +void ColumnLBClass_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags); +void ColumnLBClass_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags); +void ColumnLBClass_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags); +void ColumnLBClass_OnRButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags); + +// helper functions +int ColumnLBClass_ComputeOffsets(HWND hwnd); + +// ------------------------------------------------------------------------------------- +// +// Locals +// +BOOL fWIN32s; // flag for whether win32s (instead of win32/NT) + + +// ----------------------------------------------------------------- +// +// ColumnLBClass_Register() +// +// This function is used to register the Column LB class with the system +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +BOOL ColumnLBClass_Register(HINSTANCE hInstance) +{ + WNDCLASS WndClass; + + fWIN32s = ((DWORD)GetVersion() & 0x80000000) ? TRUE : FALSE; + + // + // Create the COLUMNLISTBOX class + // + WndClass.style = CS_PARENTDC | CS_DBLCLKS; // CS_GLOBALCLASS; + WndClass.lpfnWndProc = ColumnLBClass_WndProc; + WndClass.cbClsExtra = 0; + WndClass.cbWndExtra = sizeof(LPCOLUMNLBSTRUCT); // we store a pointer as instance data + WndClass.hInstance = hInstance; + WndClass.hIcon = 0; + WndClass.hCursor = LoadCursor(0, IDC_ARROW); + WndClass.hbrBackground = 0; + WndClass.lpszMenuName = 0; + WndClass.lpszClassName = COLUMNLBCLASS_CLASSNAME; + + /* Register the normal title list box control */ + return RegisterClass((LPWNDCLASS)&WndClass); +} + + +// ----------------------------------------------------------------- +// +// ColumnVLBClass_Register() +// +// This function is used to register the Column VLIST LB class with the system +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +BOOL ColumnVLBClass_Register(HINSTANCE hInstance) +{ + WNDCLASS WndClass; + + fWIN32s = ((DWORD)GetVersion() & 0x80000000) ? TRUE : FALSE; + + // + // Create the COLUMNVLISTBOX class + // + WndClass.style = CS_PARENTDC | CS_DBLCLKS; // CS_GLOBALCLASS; + WndClass.lpfnWndProc = ColumnLBClass_WndProc; + WndClass.cbClsExtra = 0; + WndClass.cbWndExtra = sizeof(LPCOLUMNLBSTRUCT); // we store a pointer as instance data + WndClass.hInstance = hInstance; + WndClass.hIcon = 0; + WndClass.hCursor = LoadCursor(0, IDC_ARROW); + WndClass.hbrBackground = 0; + WndClass.lpszMenuName = 0; + WndClass.lpszClassName = COLUMNVLBCLASS_CLASSNAME; // NOTE: this is a different name + + /* Register the new control */ + return(RegisterClass((LPWNDCLASS)&WndClass)); +} + + + +// ----------------------------------------------------------------- +// +// ColumnLBClass_Unregister() +// +// This function is used to deregister the Column LB class with the system +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +BOOL ColumnLBClass_Unregister(HINSTANCE hInstance) +{ + return(UnregisterClass(COLUMNLBCLASS_CLASSNAME, hInstance)); +} + +// ----------------------------------------------------------------- +// +// ColumnVLBClass_Unregister() +// +// This function is used to deregister the Column VLIST LB class with the system +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +BOOL ColumnVLBClass_Unregister(HINSTANCE hInstance) +{ + return(UnregisterClass(COLUMNVLBCLASS_CLASSNAME, hInstance)); +} + +// ----------------------------------------------------------------- +// ColumnLBClass_ListBoxWndProc +// +// Window proc used in sub-classing the internal listbox to catch +// internal scroll events to keep title in sync with it... +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +LRESULT CALLBACK ColumnLBClass_ListBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD result; + LPCOLUMNLBSTRUCT lpColumnLB; + + // Everthing goes to normal listbox for processing + lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(GetParent(hwnd), (DWORD)0); + + // preprocessing + switch (msg) + { + + case WM_HSCROLL: + // do title hscroll first.. + result = SendMessage(lpColumnLB->hwndTitleList, WM_HSCROLL, wParam, lParam); + break; + + case WM_SETFOCUS: + lpColumnLB->fHasFocus = TRUE; + //dprintf ("SetFocus to ColumnLB\n"); + break; + + case WM_KILLFOCUS: + lpColumnLB->fHasFocus = FALSE; + //dprintf ("KillFocus to ColumnLB\n"); + break; + + + } + + // + // call the original listbox window proc + // + result = CallWindowProc((WNDPROC)(lpColumnLB->OldListboxProc), hwnd, msg, (WPARAM) wParam, (LPARAM)lParam); + + + // + // or if our parent has CLBS_NOTIFYLMOUSE style, then foward LMOUSE buttons + // or if our parent has CLBS_NOTIFYRMOUSE style, then foward RMOUSE buttons + // + switch (msg) + { + case WM_HSCROLL: + // + // if it is a Horizontal scrolls, then we foward to our parent so title can be moved + // in sync with listbox.... + // + SendMessage(GetParent(hwnd), CLB_HSCROLL, wParam, lParam ); + break; + + case VLB_RESETCONTENT: + case LB_RESETCONTENT: + // + // if it is a LB_RESETCONTENT, or VLB_RESETCONTENT, then reset x position + // + SendMessage(GetParent(hwnd), CLB_HSCROLL, (WPARAM)SB_TOP, (LPARAM)NULL); + break; + + case WM_LBUTTONDOWN : + case WM_LBUTTONUP : + case WM_LBUTTONDBLCLK : + // + // forward message to parent + // + if (GetWindowLong(GetParent(hwnd), GWL_EXSTYLE) & CLBS_NOTIFYLMOUSE) + SendMessage(GetParent(hwnd), msg, wParam, lParam); + break; + + case WM_RBUTTONDOWN : +// case WM_RBUTTONUP : + case WM_RBUTTONDBLCLK : + + // + // forward message to parent + // + + // if (GetWindowLong(GetParent(hwnd), GWL_EXSTYLE) & CLBS_NOTIFYRMOUSE) + SendMessage(GetParent(hwnd), msg, wParam, lParam); + break; + + + default: + break; + } + + return(result); +} + +// ----------------------------------------------------------------- +// ColumnLBClass_TitleListBoxWndProc +// +// Window proc used in sub-classing the internal Title listbox to catch +// internal mouse click events... +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +LRESULT CALLBACK ColumnLBClass_TitleListBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD result; + LPCOLUMNLBSTRUCT lpColumnLB; + + // Everthing goes to normal listbox for processing + lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(GetParent(hwnd), (DWORD)0); + + // + // call the original listbox window proc + // + result = CallWindowProc((WNDPROC)(lpColumnLB->OldTitleListboxProc) , hwnd, msg, (WPARAM) wParam, (LPARAM)lParam); + + // + // foward LMOUSE buttons, foward RMOUSE buttons + // + switch (msg) + { +#ifdef DEBUG_HSCROLL + case WM_HSCROLL: + dprintf(TEXT("ColumnLBClass_TitleListBoxProc: CallWindowProc(OldListboxProc) returned %ld to hwnd=%lx, wParam=%u, lParam=%u\n"), hwnd, wParam, lParam); + break; +#endif + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN : + case WM_LBUTTONUP : + case WM_LBUTTONDBLCLK : + case WM_RBUTTONDOWN : + case WM_RBUTTONUP : + case WM_RBUTTONDBLCLK : + SendMessage(GetParent(hwnd), msg, wParam, lParam); + break; + + case WM_SETFOCUS: + // we don't ever want the focus, so give it back to the parent... + SendMessage(GetParent(hwnd), msg, wParam, lParam); + break; + + case WM_SIZE: + // we need to reset our idea of what our current scroll position is... + break; + } + + return(result); +} + + + +// ----------------------------------------------------------------- +// ColumnLBClass_WndProc +// +// Main window proc for handling messages for both the ColumnLB and +// ColumnVLB classes... +// +// HISTORY: +// Tom Laird-McConnell 4/17/93 Created +// +// ----------------------------------------------------------------- +LRESULT CALLBACK ColumnLBClass_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + LPCOLRECORD lpRecord; + int result; + + // + // check for ListBox message coming from application + // and forward them onto the listbox itself... + // + if ( ((fWIN32s == TRUE) && (msg >= WM_USER && msg < (WM_USER + LB_MSGMAX - LB_ADDSTRING + 1)) ) || // WIN32s version BUGBUG + ((fWIN32s == FALSE) && (msg >= LB_ADDSTRING && msg < LB_MSGMAX)) || // NT version BUGBUG + ((msg >= VLB_TOVLIST_MSGMIN) && (msg <= VLB_TOVLIST_MSGMAX)) // vlb sepcific APP->VLIST messages should be fowarded... + ) + { + // + // OWNERDRAW parent, so just send it to the hwnd list child + // + return(SendMessage(lpColumnLB->hwndList, msg, wParam, lParam)); + } + + // + // check to see if message is a TO APPLCATION message from the child listbox + // which should be forwarded to application parent window + // + if ((msg >= VLB_TOAPP_MSGMIN) && (msg <= VLB_TOAPP_MSGMAX)) + return(SendMessage(GetParent(hwnd), msg, wParam, lParam)); // forward to parent... + + // + // since it's not a message passing through, then process this message + // as our own... + // + switch (msg) + { + HANDLE_MSG(hwnd, WM_NCCREATE, ColumnLBClass_OnNCCreate); + HANDLE_MSG(hwnd, WM_NCDESTROY, ColumnLBClass_OnNCDestroy); + HANDLE_MSG(hwnd, WM_DESTROY, ColumnLBClass_OnDestroy); + HANDLE_MSG(hwnd, WM_PAINT, ColumnLBClass_OnPaint); + HANDLE_MSG(hwnd, WM_SIZE, ColumnLBClass_OnSize); + HANDLE_MSG(hwnd, WM_DRAWITEM, ColumnLBClass_OnDrawItem); + HANDLE_MSG(hwnd, WM_MEASUREITEM, ColumnLBClass_OnMeasureItem); + HANDLE_MSG(hwnd, WM_DELETEITEM, ColumnLBClass_OnDeleteItem); + + HANDLE_MSG(hwnd, WM_LBUTTONDOWN, ColumnLBClass_OnLButtonDown); + HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, ColumnLBClass_OnLButtonDown); + HANDLE_MSG(hwnd, WM_LBUTTONUP, ColumnLBClass_OnLButtonUp); + HANDLE_MSG(hwnd, WM_MOUSEMOVE, ColumnLBClass_OnMouseMove); + + case WM_RBUTTONDOWN: + // figure out what item we are on and tell our parent. + HANDLE_WM_RBUTTONDOWN ( hwnd, wParam, lParam, ColumnLBClass_OnRButtonDown ); + break; + + case WM_CREATE: + { + LPCREATESTRUCT lpCreate = (LPCREATESTRUCT) lParam; + + ColumnLBClass_OnSize(hwnd, SIZE_RESTORED, lpCreate->cx, lpCreate->cy); + } + break; + + + // ------------------------------------------------------------------- + // put System messages here which explicitly need to be passed to LISTBOX + // + case WM_SETFONT: + HANDLE_WM_SETFONT(hwnd, wParam, lParam, ColumnLBClass_OnSetFont); + break; + + // put the focus on the list box if we get it + case WM_SETFOCUS: + lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + SetFocus(lpColumnLB->hwndList); + break; + + case SBM_SETPOS : + case SBM_SETRANGE : + case SBM_SETRANGEREDRAW : + // + // need to foward SBM messages to both listboxes... + // + SendMessage(lpColumnLB->hwndTitleList, msg, wParam, lParam); + return(SendMessage(lpColumnLB->hwndList, msg, wParam, lParam)); + + case SBM_GETPOS : + case SBM_GETRANGE : + case SBM_ENABLE_ARROWS : + return(SendMessage(lpColumnLB->hwndList, msg, wParam, lParam)); + + // ------------------------------------------------------------------------------ + // + // LB_XXXXXXX Messages (disguised as CLB_XXXXXX messages) + // to pass on to child listbox, if the parent didn't want us to + // be owner draw, then we implement ownerddraw default behavior ourself + // + // ------------------------------------------------------------------------------ + case CLB_ADDSTRING: + case CLB_INSERTSTRING: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + LPTSTR lpColStart,lpTab; + LPTSTR lpStringBuffer; + int i; + + lpRecord = (LPCOLRECORD)GlobalAllocPtr(GPTR, sizeof(COLRECORD) + sizeof(LPTSTR) * lpColumnLB->nColumns); + lpStringBuffer = (LPTSTR) GlobalAllocPtr(GPTR, (lstrlen((LPTSTR)lParam) * sizeof(TCHAR)) + sizeof(TCHAR)); + + if ((lpRecord) && (lpStringBuffer)) + { + // now parse the tab-deliminated string and put into each pointer + lstrcpy(lpStringBuffer, (LPTSTR)lParam); + lpColStart = lpStringBuffer; + lpTab = lstrchr(lpStringBuffer, TEXT('\t')); + + // fill in pointer table + for (i=0; i < lpColumnLB->nColumns; i++) + { + if (lpTab) + *lpTab = '\0'; + else + { + // there was an error, not enough tabs! + GlobalFreePtr(lpRecord); + GlobalFreePtr(lpStringBuffer); + return(LB_ERR); + } + // store this pointer. + lpRecord->pString[i] = lpColStart; + // advance to next column text + lpColStart = lpTab + 1; + lpTab = lstrchr(lpColStart, TEXT('\t')); + } + lpRecord->itemData = 0; + + // and now pass on our new lpRecord as the item being added to the listbox + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, (LPARAM)lpRecord)); + } + else // an error has occured, free up any memory and return failure + { + if (lpStringBuffer) + GlobalFreePtr(lpStringBuffer); + if (lpRecord) + GlobalFreePtr(lpRecord); + return(LB_ERR); + } + } + else + // + // Parent is owner draw, so send it to the hwnd list child, + // but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + // and we also need to check for LB_GETTEXT to make it look like a string + case CLB_GETTEXT: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + LPTSTR p = (LPTSTR)lParam; + DWORD Length = 0; + DWORD x; + int i; + + *p = '\0'; + + // and now pass on to get the text... + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, wParam, 0); + + if (lpRecord == (LPCOLRECORD)LB_ERR) + return(LB_ERR); + + for (i=0; i < lpColumnLB->nColumns ; i++ ) + { + lstrcpy(p, lpRecord->pString[lpColumnLB->ColumnOrderTable[i]]); + lstrcat(p, TEXT("\t")); + x = lstrlen(p); + Length += x + sizeof(TCHAR); + p += x; + } + return(Length); + } + else + // + // Parent is owner draw, so send it to the hwnd list child, + // but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + case CLB_GETTEXTPTRS: + + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, wParam, 0); + + if (lpRecord == (LPCOLRECORD)LB_ERR) + return(LB_ERR); + + return (LRESULT)lpRecord->pString; + } + else + return (LRESULT)NULL; + + + // we need to handle LB_GETTEXTLEN to return full tabbed length... + case CLB_GETTEXTLEN: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + LPTSTR p = (LPTSTR)lParam; + DWORD Length = 0; + int i; + + // and now pass on to get the text... + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, wParam, 0); + + if (lpRecord == (LPCOLRECORD)LB_ERR) + return(LB_ERR); + + for (i=0; i < lpColumnLB->nColumns ; i++ ) + { + Length += lstrlen(lpRecord->pString[lpColumnLB->ColumnOrderTable[i]]) + sizeof(TCHAR); + } + return(Length); + } + else + // + // Parent is owner draw, so send it to the hwnd list child, + // but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + case CLB_GETITEMDATA: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, wParam, 0); + if (lpRecord != (LPCOLRECORD)LB_ERR) + return(lpRecord->itemData); + else + return(LB_ERR); + } + else + // + // Parent is owner draw, so send it to the hwnd list child, + // but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + + case CLB_SETITEMDATA: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, wParam, 0); + + if (lpRecord != (LPCOLRECORD)LB_ERR) + return(lpRecord->itemData = lParam); + else + return(LB_ERR); + } + else + // + // Parent is owner draw, so send it to the hwnd list child, + // but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + // + // if it is a HORIZONTAL exntent message, then we need to massage... + // + case CLB_SETHORIZONTALEXTENT : + // + // send the message to the title listbox as well + // + SendMessage(lpColumnLB->hwndTitleList, LB_SETHORIZONTALEXTENT, wParam, lParam); + + // + // pass it on to the child listbox, using VLB_SETHOR if appropriate... + // + return(SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_SETHORIZONTALEXTENT : LB_SETHORIZONTALEXTENT, + wParam, lParam)); + + // + // we need to massage the GETITEMRECT to handle the incorrect rect returned due to titlelistbox. + // + case CLB_GETITEMRECT: + { + int retcode; + int height; + LPRECT lpRect = (LPRECT)lParam; + + // + // send it to the hwnd list child, but translate the message first to real LB_ message + // + retcode = SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam); + height = lpRect->bottom-lpRect->top; + lpRect->top = lpRect->bottom + 1; + lpRect->bottom = lpRect->top + height; + return(retcode); + } + break; + + case CLB_DELETESTRING : + case CLB_SELITEMRANGEEX : + case CLB_RESETCONTENT : + case CLB_SETSEL : + case CLB_SETCURSEL : + case CLB_GETSEL : + case CLB_GETCURSEL : + case CLB_GETCOUNT : + case CLB_SELECTSTRING : + case CLB_DIR : + case CLB_GETTOPINDEX : + case CLB_FINDSTRING : + case CLB_GETSELCOUNT : + case CLB_GETSELITEMS : + case CLB_SETTABSTOPS : + case CLB_GETHORIZONTALEXTENT : + case CLB_SETCOLUMNWIDTH : + case CLB_ADDFILE : + case CLB_SETTOPINDEX : + case CLB_SELITEMRANGE : + case CLB_SETANCHORINDEX : + case CLB_GETANCHORINDEX : + case CLB_SETCARETINDEX : + case CLB_GETCARETINDEX : + case CLB_SETITEMHEIGHT : + case CLB_GETITEMHEIGHT : + case CLB_FINDSTRINGEXACT : + case CLB_SETLOCALE : + case CLB_GETLOCALE : + case CLB_SETCOUNT : + // + // Simply send it to the hwnd list child, but translate the message first to real LB_ message + // + return(SendMessage(lpColumnLB->hwndList, msg - CLB_BASE, wParam, lParam)); + + // ------------------------------------------------------------------- + // put messages here which explicitly need to be passed to our PARENT + // + case WM_COMMAND: + /* if this is a notification message from our child translate */ + /* it to look like it is from us and pass on to our parent */ + + if (LOWORD(wParam) == IDL_COLUMNLISTBOX) + return(SendMessage( GetParent(hwnd), + msg, + MAKELONG( GetDlgCtrlID(hwnd) ,HIWORD(wParam)), + (LPARAM)hwnd )); // make it look like we were the ones sending the message... + else + return(SendMessage(GetParent(hwnd), msg, wParam, (LPARAM)hwnd)); + + case WM_VKEYTOITEM: + // pass on to our parent but using our hwnd... + if (lpColumnLB->Style & (LBS_WANTKEYBOARDINPUT | VLBS_WANTKEYBOARDINPUT) ) + return(SendMessage(GetParent(hwnd), msg, wParam, (LPARAM)hwnd)); + else + return(-1); // perform default action... + + case WM_CHARTOITEM: + if (lpColumnLB->Style & (LBS_WANTKEYBOARDINPUT | VLBS_WANTKEYBOARDINPUT) ) + if ((result = SendMessage(GetParent(hwnd), msg, wParam, (LPARAM)hwnd)) != -1) + return(result); + + return HANDLE_WM_CHARTOITEM(hwnd, wParam, lParam, ColumnLBClass_OnCharToItem); + + case WM_COMPAREITEM: + { + LPCOMPAREITEMSTRUCT lpCompareItem = (LPCOMPAREITEMSTRUCT)lParam; + int result; + + if ((lpColumnLB->Style & LBS_OWNERDRAWFIXED) || + (lpColumnLB->Style & VLBS_OWNERDRAWFIXED)) + { + // + // substitute our values in the COMPAREITEMSTRUCT... + // + lpCompareItem->CtlID = GetDlgCtrlID(hwnd); + lpCompareItem->hwndItem = hwnd; + + // + // then pass to our parent as our WM_COMPAREITEM, with the current physcial sort column as wParam + // + result = (int)SendMessage(GetParent(hwnd), WM_COMPAREITEM, (WPARAM)lpColumnLB->SortColumn, (LPARAM)lpCompareItem); + return(result); + } + else + { + LPTSTR lpString1; + LPTSTR lpString2; + LPCOLRECORD lpColRecord1; + LPCOLRECORD lpColRecord2; + + // handle ourselves assuming item data is pointer to array of LPTSTR's + lpColRecord1 = (LPCOLRECORD)lpCompareItem->itemData1; + lpColRecord2 = (LPCOLRECORD)lpCompareItem->itemData2; + lpString1 = lpColRecord1->pString[lpColumnLB->SortColumn]; + lpString2 = lpColRecord2->pString[lpColumnLB->SortColumn]; + if (lpString1 && lpString2) + return(lstrcmpi(lpString1, lpString2)); + else + return(0); + } + } + break; + + // --------------------------------------------------------- + // handle our own messages + // --------------------------------------------------------- + + // + // NUMBER COLUMNS + // + case CLB_GETNUMBERCOLS : // get the number of columns (ret=NumCols) + return ColumnLBClass_OnNumberCols(hwnd, 0, FALSE); + + case CLB_SETNUMBERCOLS : // set the number of columns (wparam=NumCols) + return ColumnLBClass_OnNumberCols(hwnd, (BYTE)wParam, TRUE); + + // ---------------------------------------------------------------- + // Following messages use physical column numbers + // ---------------------------------------------------------------- + // + // COLUMN WIDTH + // + case CLB_GETCOLWIDTH : // get a column width (wParm=Physical Column ret=ColWidth in LU's) + return ColumnLBClass_OnColWidth(hwnd, (BYTE)wParam, (int)0, FALSE); + + case CLB_SETCOLWIDTH : // set a column width (wParm=Physical Column lParam=Width) + return ColumnLBClass_OnColWidth(hwnd, (BYTE)wParam, (int)lParam, TRUE); + + case CLB_AUTOWIDTH : // auto-matically set column widths using titles... (wParam = Physical Column to auto width) + return ColumnLBClass_OnAutoWidth(hwnd, (BYTE)wParam); + + // + // COLUMN TITLE + // + case CLB_GETCOLTITLE : // get a column's title (wParm=Physical Column, ret=Title) + return (LRESULT)ColumnLBClass_OnColTitle(hwnd, (BYTE)wParam, (LPTSTR)NULL, FALSE); + + case CLB_SETCOLTITLE : // set a column's title (wParm=Physical Col, lParm=Title) + return (LRESULT)ColumnLBClass_OnColTitle(hwnd, (BYTE)wParam, (LPTSTR)lParam, TRUE); + + case CLB_GETROWCOLTEXT: + // + // if the parent is NOT handling OWNERDRAW, then we need to handle + // + if ( ! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + INT WhichCol = (INT)(wParam); + INT WhichRow = (INT)(lParam); + + // and now pass on to get the text... + lpRecord = (LPCOLRECORD)SendMessage(lpColumnLB->hwndList, LB_GETITEMDATA, WhichRow, 0); + + if (lpRecord == (LPCOLRECORD)LB_ERR) + return((LRESULT)NULL); + + return (LRESULT)lpRecord->pString[WhichCol]; + } + return((LRESULT)NULL); // owner draw, the owner has to figure this out themselves + + + // + // SORT COLUMN + // + case CLB_GETSORTCOL : // get the physical sort column (ret=Physical Col) + return (LRESULT)ColumnLBClass_OnSortCol(hwnd, 0, FALSE); + + case CLB_SETSORTCOL : // set the physical sort column (wParm=Physical Col) + return (LRESULT)ColumnLBClass_OnSortCol(hwnd, (BYTE)wParam, TRUE); + + // + // COLUMN ORDER + // + case CLB_GETCOLORDER : // get the virtual order of physical columns (ret = LPDWORD order table) + return (LRESULT)ColumnLBClass_OnColOrder(hwnd, (LPBYTE)0, FALSE); + + case CLB_SETCOLORDER : // get the virtual order of physical columns (wParam = LPDWORD order table) + return (LRESULT)ColumnLBClass_OnColOrder(hwnd, (LPBYTE)lParam, TRUE); + + + + case CLB_CHECKFOCUS: // does the listbox have the focus? +// if (lpColumnLB->fUseVlist) // then we have to ask vlist the info +// return +// else + return lpColumnLB->fHasFocus; + + + // ---------------------------------------------------------------- + // Following messages use virtual column numbers + // ---------------------------------------------------------------- + + // + // COLUMN OFFSETS + // + case CLB_GETCOLOFFSETS : // gets the incremental virtual col offsets (ret=LPDWORD) + return (LRESULT)ColumnLBClass_OnColOffsets(hwnd, (LPINT)wParam, FALSE); + +// case CLB_SETCOLOFFSETS : // gets the incremental virtual col offsets (ret=LPDWORD) +// return (LRESULT)ColumnLBClass_OnColOffsets(hwnd, (LPDWORD)wParam, TRUE); + + + // ================================================================= + // INTERNAL + // + case CLB_HSCROLL : // a hscroll event (INTERNAL) + return ColumnLBClass_OnHScroll(hwnd, (HWND)(lParam), (int)LOWORD(wParam), (int)HIWORD(wParam)); + + + // + // GET FOCUS + // + case CLB_GETFOCUS : // get the handle for the window of CLB with the key focus + if ( lpColumnLB->fUseVlist ) + // we must ask the column list box below us for the information. + return SendMessage ( lpColumnLB->hwndList, VLB_GETFOCUSHWND, 0,0 ); + return (LRESULT) lpColumnLB->hwndList; + + default: + return(DefWindowProc(hwnd, msg, wParam, lParam)); + } + + return(TRUE); +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnNCCreate() +// +// Handles WM_NCCCREATE message +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +BOOL ColumnLBClass_OnNCCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) +{ + LPCOLUMNLBSTRUCT lpColumnLB; + HWND hwndList; + HWND hwndTitleList; + BOOL fUseVlist; + HDC hdc; + TEXTMETRIC tm; + RECT rect; + WORD ncxBorder; + WORD ncyBorder; + WORD yTitle; + + ncxBorder = GetSystemMetrics(SM_CXBORDER); + ncyBorder = GetSystemMetrics(SM_CYBORDER); + + // + // if the classname is for ColumnVLB class, then they want the Column Virtual list box... + // + if (lstrcmpi(lpCreateStruct->lpszClass, COLUMNVLBCLASS_CLASSNAME) == 0) + fUseVlist = TRUE; + else + fUseVlist = FALSE; + + hdc = GetDC(hwnd); + GetTextMetrics(hdc, &tm); + ReleaseDC(hwnd, hdc); + + yTitle = tm.tmHeight + 2*ncyBorder; + + GetClientRect(hwnd, &rect); + + // + // create the title list box window... + // + hwndTitleList = CreateWindow( (LPTSTR) TEXT("LISTBOX"), + (LPTSTR) TEXT(""), + (lpCreateStruct->style & ~WS_BORDER) | + LBS_NOINTEGRALHEIGHT | + LBS_OWNERDRAWFIXED | + WS_VISIBLE | + WS_CHILD, + ncxBorder, + ncyBorder, + lpCreateStruct->cx - (2*ncxBorder) - GetSystemMetrics(SM_CXVSCROLL), + yTitle, + hwnd, + (HMENU)IDL_COLUMNTITLELISTBOX, + lpCreateStruct->hInstance, + NULL); + + if (fUseVlist == TRUE) + // + // create a Vlist window... + // + hwndList = CreateWindow((LPTSTR)VLIST_CLASSNAME, + (LPTSTR) TEXT(""), + (lpCreateStruct->style & ~(WS_BORDER | VLBS_HASSTRINGS)) | // NOTE: This can _never_ be hasstrings + VLBS_NOTIFY | + VLBS_USETABSTOPS | + VLBS_NOINTEGRALHEIGHT | + VLBS_OWNERDRAWFIXED | // we always force this as either we will owner draw, or our parent will + WS_HSCROLL | + WS_VSCROLL | + VLBS_DISABLENOSCROLL | + WS_VISIBLE | + WS_CHILD, + ncxBorder, + yTitle + ncyBorder, + lpCreateStruct->cx - ncxBorder, // -(2*ncxBorder) + lpCreateStruct->cy - yTitle - ncyBorder, + hwnd, + (HMENU)IDL_COLUMNLISTBOX, + lpCreateStruct->hInstance, + NULL); + else + // + // create a list box window... + // +#ifdef H_SCROLL + hwndList = CreateWindow((LPTSTR) TEXT("LISTBOX"), + (LPTSTR) TEXT(""), + (lpCreateStruct->style & ~(WS_BORDER | LBS_HASSTRINGS)) | // NOTE: This can _never_ be hasstrings + LBS_NOTIFY | + LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | + LBS_OWNERDRAWFIXED | // we always force this as either we will owner draw, or our parent will + WS_HSCROLL | + WS_VSCROLL | + LBS_DISABLENOSCROLL | + WS_VISIBLE | + WS_CHILD, + ncxBorder, + yTitle + ncyBorder, + lpCreateStruct->cx - ncxBorder, // -(2*ncxBorder) + lpCreateStruct->cy - yTitle - ncyBorder, + hwnd, + (HMENU)IDL_COLUMNLISTBOX, + lpCreateStruct->hInstance, + NULL); +#else + hwndList = CreateWindow((LPTSTR) TEXT("LISTBOX"), + (LPTSTR) TEXT(""), + (lpCreateStruct->style & ~(WS_BORDER | LBS_HASSTRINGS)) | // NOTE: This can _never_ be hasstrings + LBS_NOTIFY | + LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | + LBS_OWNERDRAWFIXED | // we always force this as either we will owner draw, or our parent will + WS_VSCROLL | + LBS_DISABLENOSCROLL | + WS_VISIBLE | + WS_CHILD, + ncxBorder, + yTitle + ncyBorder, + lpCreateStruct->cx - ncxBorder, // -(2*ncxBorder) + lpCreateStruct->cy - yTitle - ncyBorder, + hwnd, + (HMENU)IDL_COLUMNLISTBOX, + lpCreateStruct->hInstance, + NULL); +#endif + + // + // if we succeeded... + // + if (hwndList) + { + // + // create a ColumnLB struct to keep track of all of the pertinent instance + // info for this instance of a ColumnLB window + // + lpColumnLB = (LPCOLUMNLBSTRUCT)GlobalAllocPtr(GPTR, sizeof(COLUMNLBSTRUCT)); + + if (lpColumnLB) + { + BYTE i; + + // + // store it in the window data for this window + // + SetWindowLong(hwnd, 0, (DWORD)lpColumnLB); + + memset(lpColumnLB, '\0', sizeof(COLUMNLBSTRUCT)); + + // + // fill in pertinent info + // + lpColumnLB->Style = lpCreateStruct->style; + + lpColumnLB->hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE); + + lpColumnLB->fUseVlist = fUseVlist; + lpColumnLB->fSorting = FALSE; + lpColumnLB->fMouseState = 0; + + lpColumnLB->hwndList = hwndList; + lpColumnLB->OldListboxProc = (FARPROC)GetWindowLong(hwndList, GWL_WNDPROC); + lpColumnLB->NewListboxProc = MakeProcInstance((FARPROC)ColumnLBClass_ListBoxWndProc, hInst); + + lpColumnLB->hwndTitleList = hwndTitleList; + lpColumnLB->OldTitleListboxProc = (FARPROC)GetWindowLong(hwndTitleList, GWL_WNDPROC); + lpColumnLB->NewTitleListboxProc = MakeProcInstance((FARPROC)ColumnLBClass_TitleListBoxWndProc, hInst); + + lpColumnLB->nColumns=1; + + lpColumnLB->yTitle = yTitle; + + // + // init sort order + // + for (i=0; i < MAX_COLUMNS ; i++ ) + lpColumnLB->ColumnOrderTable[i] = i; + + // + // sub-class the listbox window by substituting our window proc for the + // normal one... + // + SetWindowLong(hwndList, GWL_WNDPROC,(DWORD)lpColumnLB->NewListboxProc); + + // + // sub-class the title listbox window by substituting our window proc for the + // normal one... + // + SetWindowLong(hwndTitleList, GWL_WNDPROC,(DWORD)lpColumnLB->NewTitleListboxProc); + + // + // add the lpColumnLB struct as the only item in the title listbox + // + ListBox_AddString(lpColumnLB->hwndTitleList, (DWORD)lpColumnLB); + + // + // pass this on to the default window proc + // + return(FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc)); + } + else + { + return(FALSE); + } + } + else + return(FALSE); +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnDestroy() +// +// Handles WM_DESTROY message +// +// HISTORY: +// Tom Laird-McConnell 7/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnDestroy(HWND hwnd) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + + DestroyWindow(lpColumnLB->hwndTitleList); + DestroyWindow(lpColumnLB->hwndList); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnNCDestroy() +// +// Handles WM_NCDESTROY +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnNCDestroy(HWND hwnd) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + FreeProcInstance(lpColumnLB->NewListboxProc); + + GlobalFreePtr(lpColumnLB); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnPaint() +// +// Handles WM_PAINT message, draws column titles as appropriate... +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnPaint(HWND hwnd) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + PAINTSTRUCT ps; + HBRUSH hFrameBrush, hGreyBrush; + RECT rect; + HDC hdc; + int ncxBorder = GetSystemMetrics(SM_CXBORDER); + int ncyBorder = GetSystemMetrics(SM_CYBORDER); + + BeginPaint(hwnd, (LPPAINTSTRUCT)&ps); + + // Draw border around title and listbox + GetClientRect(hwnd, (LPRECT)&rect); + + hdc = ps.hdc; + + hFrameBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOWFRAME)); + FrameRect(hdc, (LPRECT)&rect, hFrameBrush); + + // make bottom the height of a HSCROLL bar + // make left side the width of a VSCROLL bar + rect.top += ncyBorder; + rect.right -= ncxBorder; + rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL); + rect.bottom = lpColumnLB->yTitle+ncyBorder; + + hGreyBrush = CreateSolidBrush(GetSysColor(COLOR_SCROLLBAR)); + FillRect(hdc, &rect, hGreyBrush); + + rect.right = rect.left+1; + FillRect(hdc, &rect, hFrameBrush); + + // destroy brushes... + DeleteBrush(hFrameBrush); + DeleteBrush(hGreyBrush); + + EndPaint(hwnd, (LPPAINTSTRUCT)&ps); +} + + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnSize() +// +// Handles WM_SIZE message +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnSize(HWND hwnd, UINT state, int cx, int cy) +{ + WORD ncxBorder; + WORD ncyBorder; + RECT rect; + DWORD cxExtent; + + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + + if (lpColumnLB->hwndList != (HWND)NULL) + { + ncxBorder = GetSystemMetrics(SM_CXBORDER); + ncyBorder = GetSystemMetrics(SM_CYBORDER); + + // position title listbox at top + MoveWindow(lpColumnLB->hwndTitleList, + ncxBorder, + ncyBorder, + cx-(2*ncxBorder) - GetSystemMetrics(SM_CXVSCROLL), + lpColumnLB->yTitle, + TRUE); + + // position list box below title listbox + MoveWindow(lpColumnLB->hwndList, + ncxBorder, + lpColumnLB->yTitle + ncyBorder, + cx - ncxBorder, // -(2*ncxBorder) + cy-lpColumnLB->yTitle - ncyBorder, + TRUE); + + cxExtent = ColumnLBClass_ComputeOffsets(hwnd); + + GetClientRect(hwnd, &rect); + + // + // if the new extent is smaller then the space available, move the position + // + if ((DWORD)rect.right > cxExtent) + { +// #ifdef DEBUG +// dprintf(TEXT("Reset HSCROLL pos to far left\n")); +// #endif + // move position to far left + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_HSCROLL : WM_HSCROLL, + MAKEWPARAM(SB_TOP, 0), 0); + + // do the same for the title list + SendMessage(lpColumnLB->hwndTitleList, + WM_HSCROLL, MAKEWPARAM(SB_TOP, 0), 0); + } + + InvalidateRect(lpColumnLB->hwndList, NULL, TRUE); + InvalidateRect(lpColumnLB->hwndTitleList, NULL, TRUE); + } + InvalidateRect(lpColumnLB->hwndTitleList, 0, TRUE); + InvalidateRect(lpColumnLB->hwndList, 0, TRUE); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnSetFont() +// +// Handles WM_SETFONT message +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnSetFont(HWND hwnd, HFONT hFont, BOOL fRedraw) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + HDC hdc; + TEXTMETRIC tm; + RECT rect; + + lpColumnLB->hFont = hFont; + + hdc = GetDC(hwnd); + SelectFont(hdc, (HFONT)hFont); + GetTextMetrics(hdc, &tm); + + // + // forward on to listbox window + // + if (lpColumnLB->hwndList != (HWND)NULL) + FORWARD_WM_SETFONT(lpColumnLB->hwndList, hFont, fRedraw, SendMessage); + + if (lpColumnLB->hwndTitleList != (HWND)NULL) + FORWARD_WM_SETFONT(lpColumnLB->hwndTitleList, hFont, fRedraw, SendMessage); + + // + // store text height... + // + lpColumnLB->yTitle = tm.tmHeight + 2*GetSystemMetrics(SM_CYBORDER); + + // + // change height appropriately + // + ListBox_SetItemHeight(lpColumnLB->hwndTitleList, 0, lpColumnLB->yTitle); + + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_SETITEMHEIGHT : LB_SETITEMHEIGHT, + 0, + tm.tmHeight); + + // + // since we changed the font size, forze a WM_SIZE to recalc the size of the window + // + GetClientRect(hwnd, &rect); + ColumnLBClass_OnSize(hwnd, SIZE_RESTORED, rect.right-rect.left, rect.bottom-rect.top); + + ReleaseDC(hwnd, hdc); +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnHScroll() +// +// +// Handles OnHScroll messages to keep title bar in ssync with listbox... +// +// HISTORY: +// Tom Laird-McConnell 5/1/93 Created +// ------------------------------------------------------------------ +LRESULT ColumnLBClass_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + + long lPos; + WORD nPos; + RECT rect; + int cxExtent; + + switch (code) + { + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + nPos = pos; + break; + + case SB_LINEUP: + case SB_LINEDOWN: + case SB_PAGEUP: + case SB_PAGEDOWN: + case SB_TOP: + case SB_BOTTOM: + case SB_ENDSCROLL: + if (lpColumnLB->fUseVlist) + nPos = (WORD)SendMessage(lpColumnLB->hwndList, VLB_GETSCROLLPOS, 0, 0); + else + nPos = GetScrollPos((hwndCtl) ? hwndCtl : lpColumnLB->hwndList, SB_HORZ); +// nPos = GetScrollPos(lpColumnLB->hwndList, SB_HORZ); + break; + + default: + return(TRUE); + } + + GetClientRect(lpColumnLB->hwndList, (LPRECT)&rect); + + //... if it is a VLIST, then there is an error in the client calculation when it has VSCROLL bars, so + // we need to adjust ourselves by width of VSCROLL bar... + if (lpColumnLB->fUseVlist) + rect.right -= GetSystemMetrics(SM_CXVSCROLL); + + cxExtent = (DWORD)SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_GETHORIZONTALEXTENT : LB_GETHORIZONTALEXTENT, 0, 0L); + if (cxExtent >= rect.right) + { + // then the listbox size is > then client's display size + // so we need to calculate how much is not on the client display + cxExtent -= rect.right; + } + else + // else set the amount left over to 0 to nullify (technical term) the + // effects of this calculation... + cxExtent = 0; + + lPos = -(((LONG)nPos*(LONG)cxExtent)/100); + if (lPos > 0) + lpColumnLB->xPos = 0; + else + if (lPos < -cxExtent) + lpColumnLB->xPos = -cxExtent; + else + lpColumnLB->xPos = (int)lPos; +} + + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnMeasureItem() +// +// +// Handles telling the parent how to draw each column accordingly... +// +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpMeasureItem) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + TEXTMETRIC tm; + HDC hdc; + + if (lpMeasureItem->CtlID == IDL_COLUMNTITLELISTBOX) + { + if (lpColumnLB) + lpMeasureItem->itemHeight = lpColumnLB->yTitle; + else + { + hdc = GetDC(hwnd); + GetTextMetrics(hdc, &tm); + ReleaseDC(hwnd, hdc); + + lpMeasureItem->itemHeight = tm.tmHeight; + } + } + else + // + // it should be passed to parent + // + FORWARD_WM_MEASUREITEM(GetParent(hwnd), lpMeasureItem, SendMessage); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnDeleteItem() +// +// +// Handles deleting items if necessary... +// +// +// HISTORY: +// Tom Laird-McConnell 08/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnDeleteItem(HWND hwnd, const DELETEITEMSTRUCT *lpDeleteItem) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + LPCOLRECORD lpRecord; + + // don't actually do the delete if we are sorting... + if (lpColumnLB->fSorting == TRUE) + return; + + if (lpDeleteItem->CtlID == IDL_COLUMNLISTBOX) + { + // if the style is that the owner is handling the owner draw stuff + // then we need to pass to the parent ELSE free our memory... + if ((lpColumnLB) && (lpColumnLB->Style & LBS_OWNERDRAWFIXED)) + // + // it should be passed to parent + // + FORWARD_WM_DELETEITEM(GetParent(hwnd), lpDeleteItem, SendMessage); + else + // this is our item data, so we need to free it + if (lpDeleteItem->itemData) + { + lpRecord = (LPCOLRECORD)lpDeleteItem->itemData; + // NOTE that the first pointer is actually the string buffer... + if (lpRecord->pString[0]) + GlobalFreePtr(lpRecord->pString[0]); + GlobalFreePtr(lpRecord); + } + } +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnDrawItem() +// +// +// Handles telling the parent to draw each column accordingly... +// +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + HWND hwndParent = GetParent(hwnd); + BYTE i; + BYTE PhysCol; + CLBDRAWITEMSTRUCT CLBDrawItemStruct; + RECT rect; + int ncxBorder = GetSystemMetrics(SM_CXBORDER); + int ncyBorder = GetSystemMetrics(SM_CYBORDER); + HPEN hFramePen; + HPEN hShadowPen; + HPEN hHighlightPen; + HPEN hOldPen; + HBRUSH hBackgroundBrush; + DWORD Col; + DWORD cyChar; + TEXTMETRIC tm; + BYTE PhysColumn; + RECT ClientRect; + + GetClientRect(lpDrawItem->hwndItem, &ClientRect); + + // + // figure out which window sent us the DrawItem + // + switch (lpDrawItem->CtlID) + { + // + // handle drawing the title listbox + // + case IDL_COLUMNTITLELISTBOX: + { + + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + + if (lpDrawItem->itemAction == ODA_DRAWENTIRE) + { + GetTextMetrics(lpDrawItem->hDC, &tm); + + cyChar = tm.tmHeight; + + // + // create all of our pens for our drawing + // + hHighlightPen = CreatePen(PS_SOLID, ncyBorder, GetSysColor(COLOR_BTNHIGHLIGHT)); + hShadowPen = CreatePen(PS_SOLID, ncyBorder, GetSysColor(COLOR_BTNSHADOW)); + hFramePen = CreatePen(PS_SOLID, ncyBorder, GetSysColor(COLOR_WINDOWFRAME)); + + hBackgroundBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); + + // + // get the window rect we are going to work with + // + CopyRect(&rect, &lpDrawItem->rcItem); + FillRect(lpDrawItem->hDC, &rect, hBackgroundBrush); + + // + // Draw frame color line below title section of property window + // + hOldPen = SelectObject(lpDrawItem->hDC, hFramePen); + MoveToEx(lpDrawItem->hDC, rect.left, rect.bottom, NULL); + LineTo(lpDrawItem->hDC, rect.right, rect.bottom); + + // + // we start at the current left + // + rect.top += 2*ncyBorder; + + SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_BTNTEXT)); + SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_BTNFACE)); + + SetBkMode(lpDrawItem->hDC, TRANSPARENT); + + for (Col=0; Col < lpColumnLB->nColumns; Col++) + { + // + // get the index number of the current column + // + PhysColumn = lpColumnLB->ColumnOrderTable[Col]; + + // + // adjust right side to be left side plus width of current column + // + rect.right = rect.left + lpColumnLB->ColumnInfoTable[PhysColumn].Width; + + // + // if the button is dpressed, then draw it that way + // + if (lpColumnLB->ColumnInfoTable[PhysColumn].fDepressed) + { + // + // pick the shadow pen and draw the top-left depressed + // + SelectObject(lpDrawItem->hDC, hShadowPen); + MoveToEx(lpDrawItem->hDC, rect.left, rect.bottom, NULL); + LineTo(lpDrawItem->hDC, rect.left, rect.top-2*ncyBorder); // bottom-left --> top-left + LineTo(lpDrawItem->hDC, rect.right, rect.top-2*ncyBorder); // top-left --> top-right + + // + // pick the Frame pen and draw the Column seperater + // + SelectObject(lpDrawItem->hDC, hFramePen); + MoveToEx(lpDrawItem->hDC, rect.right+ncxBorder, rect.top-2*ncyBorder, NULL); + LineTo(lpDrawItem->hDC, rect.right+ncxBorder, rect.bottom); // bottom-left --> top-left + + // + // move the cursor for whitespace to draw text + // + rect.left += WHITESPACE/2; + + // draw the title of the column in the current slot + DrawText(lpDrawItem->hDC, + lpColumnLB->ColumnInfoTable[PhysColumn].lpTitle, + -1, + (LPRECT)&rect, + DT_SINGLELINE | DT_LEFT | DT_TOP); + rect.left -= WHITESPACE/2; // restore the left position... + } + else + { + // it is not depressed, draw it normal + + // + // pick the white pen and draw the top-left highlight + // + SelectObject(lpDrawItem->hDC, hHighlightPen); + MoveToEx(lpDrawItem->hDC, rect.left, rect.bottom-ncyBorder, NULL); + LineTo(lpDrawItem->hDC, rect.left, rect.top-2*ncyBorder); // bottom-left --> top-left + LineTo(lpDrawItem->hDC, rect.right, rect.top-2*ncyBorder); // top-left --> top-right + + // + // pick the shadow pen and draw the bottom-right dark shadow + // + SelectObject(lpDrawItem->hDC, hShadowPen); + LineTo(lpDrawItem->hDC, rect.right, rect.bottom-ncyBorder); // top-right --> bottom-right + LineTo(lpDrawItem->hDC, rect.left, rect.bottom-ncyBorder); // bottom-right --> bottom-left + + // + // pick the Frame pen and draw the Column seperater + // + SelectObject(lpDrawItem->hDC, hFramePen); + MoveToEx(lpDrawItem->hDC, rect.right+ncxBorder, rect.top-2*ncyBorder, NULL); + LineTo(lpDrawItem->hDC, rect.right+ncxBorder, rect.bottom); // bottom-left --> top-left + + // + // move the cursor for whitespace to draw text + // + rect.left += WHITESPACE/4; + + rect.top -= ncyBorder; + + // draw the title of the column in the current slot + DrawText(lpDrawItem->hDC, + lpColumnLB->ColumnInfoTable[PhysColumn].lpTitle, + -1, + (LPRECT)&rect, + DT_SINGLELINE | DT_LEFT | DT_TOP); + + rect.top += ncyBorder; + } + + // + // adjust the left side of the rect for the width of this column + // + rect.left = rect.right+2*ncxBorder; + } + + // select the original brush + SelectObject(lpDrawItem->hDC, hOldPen); + + // delete my pens + DeletePen(hFramePen); + DeletePen(hHighlightPen); + DeletePen(hShadowPen); + + DeleteBrush(hBackgroundBrush); + } + } + break; + + // + // handle sending CLB_DRAWITEM MESSAGES to parent + // + case IDL_COLUMNLISTBOX: + { + // + // make a copy of the drawitem portion of the struct + // + memcpy(&CLBDrawItemStruct.DrawItemStruct, lpDrawItem, sizeof(DRAWITEMSTRUCT)); + + // + // fake parent window into thinking our id is the listbox + // + CLBDrawItemStruct.DrawItemStruct.CtlID = GetDlgCtrlID(hwnd); + CLBDrawItemStruct.lpColOrder = lpColumnLB->ColumnOrderTable; + CLBDrawItemStruct.nColumns = lpColumnLB->nColumns; + + CopyRect(&rect, &lpDrawItem->rcItem); + + // + // move the cursor for whitespace to draw text + // + rect.left += WHITESPACE/4; + + // + // tell the parent to draw each physical column in the appropriate rectangle + // + for (i=0; i < lpColumnLB->nColumns ;i++ ) + { + // + // get physical column number + // + PhysCol = lpColumnLB->ColumnOrderTable[i]; + + // + // massage the rect's right to be the left plus the width of the column + // + rect.right = rect.left + lpColumnLB->ColumnInfoTable[PhysCol].Width - WHITESPACE/4; + + // + // copy it + // + CopyRect(&CLBDrawItemStruct.rect[i], &rect); + + // + // massage the rect's left to be the right + 1 + // + rect.left = rect.right + WHITESPACE/4 + 2*ncxBorder ; + } + + if ((lpColumnLB->Style & LBS_OWNERDRAWFIXED) || + (lpColumnLB->Style & VLBS_OWNERDRAWFIXED) ) + // + // send a draw message with the physical column order list + // to the parent as they want to draw it + // + SendMessage(hwndParent, CLBN_DRAWITEM, (WPARAM)0, (WPARAM)&CLBDrawItemStruct); + else + { + // + // we want to draw it ourselves... + // NOTE: This assumes that we are LBS_HASSTRINGS and NOT LBS_OWNERDRAWFIXED + // + switch(lpDrawItem->itemAction) + { + case ODA_FOCUS: + DrawFocusRect(lpDrawItem->hDC,(LPRECT)&(lpDrawItem->rcItem)); + break; + + case ODA_DRAWENTIRE: + case ODA_SELECT: + // only if we have data... + if (lpDrawItem->itemData) + { + LPCOLRECORD lpColRecord = (LPCOLRECORD)lpDrawItem->itemData; + + if ((lpColRecord == NULL) || + (lpColRecord == (LPCOLRECORD)LB_ERR)) + break; // bogus data + + + // Are we highlighted? (highlit?) + if (lpDrawItem->itemState & ODS_SELECTED) + { + hBackgroundBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + else + { + hBackgroundBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); + SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW)); + SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT)); + } + // FillRect(lpDrawItem->hDC,(LPRECT)&(lpDrawItem->rcItem), hBackgroundBrush); + + // + // either way, draw column borders now... + // + hFramePen = CreatePen(PS_SOLID, ncyBorder, GetSysColor(COLOR_WINDOWFRAME)); + + hOldPen = SelectObject(lpDrawItem->hDC, hFramePen); + + // + // now draw each column in the approved order... + // + for (i=0; i < CLBDrawItemStruct.nColumns ; i++) + { + // + // draw line of text... + // + ExtTextOut( lpDrawItem->hDC, + CLBDrawItemStruct.rect[i].left, + CLBDrawItemStruct.rect[i].top, + ETO_CLIPPED | ETO_OPAQUE, + &CLBDrawItemStruct.rect[i], + lpColRecord->pString[CLBDrawItemStruct.lpColOrder[i]], // pointer to string + lstrlen(lpColRecord->pString[CLBDrawItemStruct.lpColOrder[i]]), // length + (LPINT)NULL); + + // draw column seperator + ColumnLB_DrawColumnBorder( lpDrawItem->hDC, &CLBDrawItemStruct.rect[i], ClientRect.bottom, hBackgroundBrush); + } + + // restore old pen + SelectObject(lpDrawItem->hDC, hOldPen); + + // destroy pen + DeletePen(hFramePen); + + DeleteBrush(hBackgroundBrush); + } + break; + } // end of switch on drawitem action + } + + } + break; + } +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnCharToItem() +// +// Handles converting keystrokes to items +// +// HISTORY: +// Tom Laird-McConnell 10/18/93 Created +// ------------------------------------------------------------------ +int ColumnLBClass_OnCharToItem(HWND hwnd, UINT ch, HWND hwndListbox, int iCaret) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + LPCOLRECORD lpColRecord; + int nCount; + int nCurSel; + int nNewSel; + TCHAR cKey; + TCHAR cLBText; + + if (hwndListbox != lpColumnLB->hwndTitleList) + { + RECT ClientRect; + GetClientRect(hwnd, &ClientRect); + + // + // if the parent is NOT ownerdraw, then we are doing it ourselves, and + // so need to translate the WM_CHAR --> the correct item based on the + // current sort column... + // + if (! (lpColumnLB->Style & (LBS_OWNERDRAWFIXED | VLBS_OWNERDRAWFIXED)) ) + { + nCurSel = ListBox_GetCurSel(lpColumnLB->hwndList); + if (IsCharAlphaNumeric((TCHAR)ch)) + { + nNewSel = nCurSel + 1; + nCount = ListBox_GetCount(lpColumnLB->hwndList); + cKey = toupper( (TCHAR)ch ); + + // loop thru items starting with the one just after + // the current selection, until we are too far along, + // then wrap around to the beginning and + // keep going until we hit our original selection. + for (; nNewSel != nCurSel ; nNewSel++ ) + { + // make sure that we do't try to compare at location -1 + if( nNewSel == -1) + continue; + + lpColRecord = (LPCOLRECORD)ListBox_GetItemData(lpColumnLB->hwndList, nNewSel); + + // if this comes back as LB_ERR then we are off the end of the list + if( lpColRecord == (LPCOLRECORD)LB_ERR ) + { + nNewSel = -1; // increment will move to 0 + continue; + } + + cLBText = toupper( *lpColRecord->pString[ + lpColumnLB->ColumnOrderTable[ + lpColumnLB->SortColumn ]] ); + + if ( cLBText == cKey ) + { + // we found it ... + // change the current selection + if( lpColumnLB->Style & LBS_MULTIPLESEL ) + { + // multiple selection LB, just move fuzzy rect + ListBox_SetCaretIndex(lpColumnLB->hwndList, nNewSel); + + // BUGBUG change of caret does not have a notification? + } + else + { + // single sel LB, change the sel + ListBox_SetCurSel(lpColumnLB->hwndList, nNewSel); + + // notify our parent if we need to + if( lpColumnLB->Style & LBS_NOTIFY ) + { + SendMessage( GetParent( hwnd ), + WM_COMMAND, + MAKEWPARAM( GetDlgCtrlID( hwnd), LBN_SELCHANGE), + (LPARAM)hwnd); // NOTE: substitute ourselves + // as the source of the message + } + } + + return(-1); // we handled it... + } + else if (nNewSel == nCount-1) + { + // we have gone beyond it + // or are at the end of the list... + + // we need to wrap to the beginning + // (this will get incremented above prior to use) + nNewSel = -1; + continue; + } + } + + // we did not find our target + return(nCurSel); + } + else + // not an alphanumeric, just return the current selection + return(nCurSel); + } + else + // + // pass on to parent as a WM_CHARTOITEM, but with the HIWORD(wParam) == SORT COLUMN + // + return(SendMessage( GetParent(hwnd), + CLBN_CHARTOITEM, + MAKEWPARAM(ch, lpColumnLB->SortColumn), + (LPARAM)hwnd)); + } +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnNumberCols() +// +// case CLB_GETNUMBERCOLS : // get the number of columns (ret=NumCols) +// case CLB_SETNUMBERCOLS : // set the number of columns (wparam=NumCols) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +BYTE ColumnLBClass_OnNumberCols(HWND hwnd, BYTE NewNumberCols, BOOL fSetColumns) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + + // + // if we are modifying it + // + if (fSetColumns) + { + // + // if the value is a new value + // + if (lpColumnLB->nColumns != NewNumberCols) + { + lpColumnLB->nColumns = NewNumberCols; + + // force a redraw of the entire columnlb... + InvalidateRect(hwnd, NULL, TRUE); + } + } + return lpColumnLB->nColumns; +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnColWidth() +// +// case CLB_GETCOLWIDTH : // get a column width (wParm=Physical Column ret=ColWidth in DU's) +// case CLB_SETCOLWIDTH : // set a column width (wParm=Physical Column lParam=Width) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +int ColumnLBClass_OnColWidth(HWND hwnd, BYTE Column, int NewWidth, BOOL fSetWidth) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + int cxExtent; + RECT rect; + + // + // if we are modifying it + // + if (fSetWidth) + { + // + // if the value is a new value + // + if (lpColumnLB->ColumnInfoTable[Column].Width != NewWidth) + { + lpColumnLB->ColumnInfoTable[Column].Width = NewWidth; + + cxExtent = ColumnLBClass_ComputeOffsets(hwnd); + + GetClientRect(hwnd, &rect); + + // + // send the message to the title listbox as well + // + SendMessage(lpColumnLB->hwndTitleList, LB_SETHORIZONTALEXTENT, cxExtent, 0L); + + // + // pass it on to the child listbox, using VLB_SETHOR if appropriate... + // + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_SETHORIZONTALEXTENT : LB_SETHORIZONTALEXTENT, cxExtent, 0L); + + // + // if the new extent is smaller then the space available, move the position + // + if (rect.right > cxExtent) + { +// #ifdef DEBUG +// dprintf(TEXT("Reset HSCROLL pos to far left\n")); +// #endif + // move position to far left + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_HSCROLL : WM_HSCROLL, + MAKEWPARAM(SB_TOP, 0), 0); + + // do the same for the title list + SendMessage(lpColumnLB->hwndTitleList, + WM_HSCROLL, MAKEWPARAM(SB_TOP, 0), 0); + } + + InvalidateRect(lpColumnLB->hwndList, NULL, TRUE); + InvalidateRect(lpColumnLB->hwndTitleList, NULL, TRUE); + } + } + return (DWORD)lpColumnLB->ColumnInfoTable[Column].Width; +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnColTitle() +// +// case CLB_GETCOLTITLE : // get a column's title (wParm=Physical Column, ret=Title) +// case CLB_SETCOLTITLE : // set a column's title (wParm=Physical Col, lParm=Title) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +LPTSTR ColumnLBClass_OnColTitle(HWND hwnd, BYTE Column, LPTSTR lpTitle, BOOL fSetTitle) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + + // + // if we are modifying it + // + if (fSetTitle) + { + // + // if the value is a new value + // + if (lpColumnLB->ColumnInfoTable[Column].lpTitle != lpTitle) + { + // + // BUGBUG, is there more to do here? + // + lpColumnLB->ColumnInfoTable[Column].lpTitle = lpTitle; + + // + // invalidate the title + // + InvalidateRect(lpColumnLB->hwndTitleList, NULL, TRUE); + } + } + return (LPTSTR)lpColumnLB->ColumnInfoTable[Column].lpTitle; +} + + + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnSortCol() +// +// case CLB_GETSORTCOL : // get the sort column (ret=Physical Col) +// case CLB_SETSORTCOL : // set the sort column (wParm=Physical Col) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +BYTE ColumnLBClass_OnSortCol(HWND hwnd, BYTE NewSortCol, BOOL fSetSortCol) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + DWORD nCount; + LPDWORD lpListboxContents; + DWORD i; + int nCurSel; + DWORD ItemData; + HCURSOR hCursor; + + // + // if we are modifying it + // + if (fSetSortCol) + { + hCursor = SetCursor(LoadCursor(0, IDC_WAIT)); + + // set new sort value + lpColumnLB->SortColumn = NewSortCol; + + // need to resort listbox + nCount = ListBox_GetCount(lpColumnLB->hwndList); + + // need to get current select + nCurSel = ListBox_GetCurSel(lpColumnLB->hwndList); + + // and it's item data + ItemData = ListBox_GetItemData(lpColumnLB->hwndList, nCurSel); + + SetWindowRedraw(lpColumnLB->hwndList, FALSE); + + // + // allocate space for the listbox contents + // + lpListboxContents = (LPDWORD) GlobalAllocPtr(GPTR, sizeof(DWORD) * nCount); + + // + // retrieve all of the data values + // + for (i=0; ihwndList, i); + + // + // reset the listbox contents + // + lpColumnLB->fSorting = TRUE; // disable deleting while sorting... + SendMessage(lpColumnLB->hwndList, LB_RESETCONTENT, 0, 0); + lpColumnLB->fSorting = FALSE; // reenable it... + + // + // now re-add all of the items, with the new sort column + // + for (i=0; ihwndList, lpListboxContents[i]); + } + + // reselect selected item... + for (i=0; i < nCount ; i++) + { + if (ItemData == (DWORD)ListBox_GetItemData(lpColumnLB->hwndList, i)) + // then select it + ListBox_SetCurSel(lpColumnLB->hwndList, i); + } + + GlobalFreePtr(lpListboxContents); + + SetWindowRedraw(lpColumnLB->hwndList, TRUE); + + InvalidateRect(lpColumnLB->hwndList, NULL, TRUE); + + SetCursor(hCursor); + } + return lpColumnLB->SortColumn; +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnColOrder() +// +// case CLB_GETCOLORDER : // get the virtual order of the physical columns (ret=LPDWORD order table) +// case CLB_SETCOLORDER : // set the virtual order of the physical columns (ret=LPDWORD order table, wParamn=LPDWORD new order) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +LPBYTE ColumnLBClass_OnColOrder(HWND hwnd, LPBYTE NewColOrder, BOOL fSetOrder) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + + // + // if we are modifying it + // + if (fSetOrder) + { + // + // copy the new order over the old order + // + memcpy(lpColumnLB->ColumnOrderTable, NewColOrder, lpColumnLB->nColumns); + + ColumnLBClass_ComputeOffsets(hwnd); + + // + // cause listbox to be redrawn + // + InvalidateRect(lpColumnLB->hwndTitleList, NULL, TRUE); + InvalidateRect(lpColumnLB->hwndList, NULL, TRUE); + } + + return lpColumnLB->ColumnOrderTable; +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnColOffsets() +// +// case CLB_GETCOLOFFSETS : // gets the incremental col offsets (ret=LPDWORD) +// case CLB_SETCOLOFFSETS : // sets the incremental col offsets (wParam = LPDWORD) +// +// HISTORY: +// Tom Laird-McConnell 4/18/93 Created +// ------------------------------------------------------------------ +LPINT ColumnLBClass_OnColOffsets(HWND hwnd, LPINT NewOffsetTable, BOOL fSetOffsets) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + + // + // if we are modifying it + // +// if (fSetOffsets) +// { +// for (i=0; i < lpColumnLB->nColumns ; i++ ) +// { +// lpColumnLB->ColumnOffsetTable[i] = NewOffsetTable[i]; +// } +// } + return (lpColumnLB->ColumnOffsetTable); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnAutoWidths() +// +// +// Handles CLB_AUTOWIDTHS messages to calculate the width of each field, and +// to calculate the offsets automatically... (if column is -1 , then all columns) +// ColumnToCompute is in Physical Columns +// +// returns: The horiztonal extent of all of the columns... +// +// HISTORY: +// Tom Laird-McConnell 5/1/93 Created +// ------------------------------------------------------------------ +LRESULT ColumnLBClass_OnAutoWidth(HWND hwnd, BYTE ColumnToCompute) +{ + HDC hdc; + BYTE nColumn; + LONG cxExtent; + SIZE Size; + TEXTMETRIC tm; + LPCOLUMNINFO lpColumnInfo, lpPrevColumnInfo; + + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0); + HFONT hOldFont; + DWORD OldStyle, NewStyle; + + hdc = GetDC(hwnd); + GetTextMetrics(hdc, &tm); + hOldFont = SelectFont(hdc, lpColumnLB->hFont); + lpPrevColumnInfo = NULL; + + // + // based on column order, compute the widths and offsets of each column + // NOTE: nColumn is the physical column + // + lpColumnInfo = lpColumnLB->ColumnInfoTable; + cxExtent = 0; + for (nColumn=0; nColumn < lpColumnLB->nColumns; nColumn++, lpColumnInfo++) + { + // bail out if column title is not there... + if ((lpColumnInfo->lpTitle == NULL) || + (lpColumnInfo->lpTitle[0] == '\0')) + continue; // try next column + + // + // only if it is a column we are supposed to change + // + if ((ColumnToCompute == (BYTE)-1) || + (nColumn == ColumnToCompute)) + { + GetTextExtentPoint( hdc, + (LPTSTR)lpColumnInfo->lpTitle, + lstrlen(lpColumnInfo->lpTitle), + &Size); + + // + // the width is the text extent of the string plus some whitespace + // + lpColumnInfo->Width = (WHITESPACE/2) + Size.cx; + } + } + + SelectFont(hdc, hOldFont); + ReleaseDC(hwnd, hdc); + + // + // now adjust the offsets to show new values + // + cxExtent = ColumnLBClass_ComputeOffsets(hwnd); + + if (lpColumnLB->fUseVlist) + OldStyle = SendMessage(lpColumnLB->hwndList, VLB_GETLISTBOXSTYLE, 0L, 0L); + else + OldStyle = GetWindowLong(lpColumnLB->hwndList, GWL_STYLE); + + // + // send the message to the title listbox as well + // + SendMessage(lpColumnLB->hwndTitleList, LB_SETHORIZONTALEXTENT, cxExtent, 0L); + + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_SETHORIZONTALEXTENT : LB_SETHORIZONTALEXTENT, cxExtent, 0L); + + if (lpColumnLB->fUseVlist) + NewStyle = SendMessage(lpColumnLB->hwndList, VLB_GETLISTBOXSTYLE, 0L, 0L); + else + NewStyle = GetWindowLong(lpColumnLB->hwndList, GWL_STYLE); + + // + // if the horizontal scroll bar is gone, then reset hscroll position + // + if ((NewStyle & WS_HSCROLL) != + (OldStyle & WS_HSCROLL)) + { + // move position to far left + SendMessage(lpColumnLB->hwndList, + (lpColumnLB->fUseVlist) ? VLB_HSCROLL : WM_HSCROLL, + MAKEWPARAM(SB_TOP, 0), 0); + } + + InvalidateRect(lpColumnLB->hwndList, NULL, TRUE); + InvalidateRect(lpColumnLB->hwndTitleList, NULL, TRUE); + + return(cxExtent); +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_ComputeOffsets() +// +// returns text extent... +// +// HISTORY: +// Tom Laird-McConnell 5/3/93 Created +// ------------------------------------------------------------------ +int ColumnLBClass_ComputeOffsets(HWND hwnd) +{ + BYTE i; + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + LPINT lpOffset; + LPBYTE lpOrder; + LPCOLUMNINFO lpColumnInfo; + BYTE PhysColumn; + int ncxBorder = GetSystemMetrics(SM_CXBORDER); + + // + // recalc the offsets table using the current virtual order + // + lpOffset = lpColumnLB->ColumnOffsetTable; + lpOrder = lpColumnLB->ColumnOrderTable; + lpColumnInfo = lpColumnLB->ColumnInfoTable; + // + // first offset is always 0 + // + lpOffset[0] = 0; + for (i=1; i < lpColumnLB->nColumns + 1 ; i++ ) + { + PhysColumn = lpOrder[i-1]; + + // + // this offset is the previous offset plus the previous width + // + lpOffset[i] = lpOffset[i-1] + lpColumnInfo[PhysColumn].Width + 2 * ncxBorder; + } + // + // last offset is also new text extent... + return(lpOffset[lpColumnLB->nColumns]); +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnLButtonDown() +// +// Handles WM_LBUTTONDOWN and WM_LBUTTONDBLCLK messages from the client +// area above the listbox +// +// +// HISTORY: +// Tom Laird-McConnell 5/3/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + BYTE i; + int AdjustedX = x - lpColumnLB->xPos; + HCURSOR hCursor; + BYTE PhysColumn; + BYTE VirtColumn; + RECT rect; + POINT point; + + point.x = x; + point.y = y; + GetClientRect(lpColumnLB->hwndTitleList, &rect); + + // only if this is a right mouse button from + if (PtInRect(&rect, point)) + { + // + // if this is a down-click, and it is on a column border, then go into resize mode + // + for(i=1; i < lpColumnLB->nColumns+1; i++) + { + // + // check to see if this is a column offset + // + if ((AdjustedX > lpColumnLB->ColumnOffsetTable[i]-4) && + (AdjustedX < lpColumnLB->ColumnOffsetTable[i]+4)) + { + VirtColumn = i-1; + PhysColumn = lpColumnLB->ColumnOrderTable[VirtColumn]; + + // + // x is the right-side of the column i-1 + // + lpColumnLB->fMouseState = MOUSE_COLUMNRESIZE; + lpColumnLB->xPrevPos = 0; + lpColumnLB->ColClickStart = VirtColumn; // virtual column + SetCapture(hwnd); + + hCursor = LoadCursor(lpColumnLB->hInstance, TEXT("SizebarHCursor")); + SetCursor(hCursor); + return; + } +#ifdef DRAG + else + // + // if this is a down-click, and it is on a column title, + // + if ((AdjustedX > lpColumnLB->ColumnOffsetTable[i-1]) && + (AdjustedX < lpColumnLB->ColumnOffsetTable[i])) + { + // + // whether it is a double-or single click, we need to draw down button state + // + VirtColumn = i-1; + PhysColumn = lpColumnLB->ColumnOrderTable[VirtColumn]; + + lpColumnLB->ColumnInfoTable[PhysColumn].fDepressed = TRUE; + + GetClientRect(lpColumnLB->hwndTitleList, &rect); + rect.left = lpColumnLB->ColumnOffsetTable[VirtColumn] + lpColumnLB->xPos; + rect.right = lpColumnLB->ColumnOffsetTable[VirtColumn+1] + lpColumnLB->xPos; + + // + // if this is a double-click, AND we are in sort mode then handle this as a sort request on the + // column double-clicked on + // + if (fDoubleClick) + { + if (GetWindowLong(hwnd, GWL_STYLE) & LBS_SORT) + { + // + // then default to doing a sort + // + SendMessage(hwnd, CLB_SETSORTCOL, (WPARAM)PhysColumn, (LPARAM)0); + } + else + { + // + // tell parent that the user double-clicked on PhysColumn + // + SendMessage(GetParent(hwnd), CLBN_TITLEDBLCLK, (WPARAM)GetDlgCtrlID(hwnd), (LPARAM) PhysColumn); + } + // + // we are done with double-click, so redraw window + // + lpColumnLB->ColumnInfoTable[PhysColumn].fDepressed = FALSE; + + InvalidateRect(lpColumnLB->hwndTitleList, &rect, FALSE); + + return; + } + else + { + // then go into single click mode/or column drag mode + + // + // then x, y is in column i-1 + // + lpColumnLB->fMouseState = MOUSE_COLUMNCLICK; + lpColumnLB->ColClickStart = VirtColumn; + + CopyRect(&lpColumnLB->ColClickRect, &rect); + + // lpColumnLB->ColClickRect.left += (lpColumnLB->ColClickRect.right - lpColumnLB->ColClickRect.left)/3; + // lpColumnLB->ColClickRect.right -= (lpColumnLB->ColClickRect.right - lpColumnLB->ColClickRect.left)/3; + + SetCapture(hwnd); + InvalidateRect(lpColumnLB->hwndTitleList, &rect, FALSE); + + GetWindowRect(lpColumnLB->hwndTitleList, &rect); + ClipCursor(&rect); + return; + } + } +#endif + } + } +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnMouseMove() +// +// Handles Mouse movement messages from the client +// area above the listbox +// +// +// HISTORY: +// Tom Laird-McConnell 5/3/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + RECT rect; + HDC hdc; + BYTE i; + int AdjustedX = x - lpColumnLB->xPos; + POINT Point; + HCURSOR hCursor; + + switch (lpColumnLB->fMouseState) + { + case 0 : // not in mouse mode at all, so just track changing cursor when over column border + for(i=1; i < lpColumnLB->nColumns + 1; i++) + { + // + // check to see if this is a column offset + // + if ((AdjustedX > lpColumnLB->ColumnOffsetTable[i]-4) && + (AdjustedX < lpColumnLB->ColumnOffsetTable[i]+4)) + { + // + // it is, so set the cursor and return + // + hCursor = LoadCursor(lpColumnLB->hInstance, TEXT("SizebarHCursor")); + SetCursor(hCursor); + return; + } + } + SetCursor(LoadCursor(0,IDC_ARROW)); + break; + + case MOUSE_COLUMNRESIZE: + GetClientRect(hwnd, &rect); + + // + // as long as we haven't moved past the previous column, and we haven't moved out of the rect + // + if (AdjustedX < lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]+8) + { + x += (lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]+8)-AdjustedX; + AdjustedX = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]+8; + } + + if (x < rect.right) + { + hdc = GetDC(hwnd); + + // un invert previous postion + if (lpColumnLB->xPrevPos) + { + rect.left = lpColumnLB->xPrevPos; + rect.right = rect.left+1; + InvertRect(hdc, &rect); + } + + lpColumnLB->xPrevPos = x; + + // invert new position + rect.left = x; + rect.right = rect.left+1; + InvertRect(hdc, &rect); + + ReleaseDC(hwnd, hdc); + } + break; + + case MOUSE_COLUMNDRAG: + // + // if this is a column drag, we track the messages until the mouse has moved + // back INTO the original column rectangle, if it does this, then we switchback to + // COLUMNCLICK mode, until they let go, or move back out + // + Point.x = x; + Point.y = y; + + GetClientRect(lpColumnLB->hwndTitleList, &rect); + + // if it is on far RIGHT generate WM_HSCROLL right message + if (x >= rect.right-2) + { + SendMessage(lpColumnLB->hwndList, (lpColumnLB->fUseVlist) ? VLB_HSCROLL : WM_HSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM)NULL); + return; + } + + // if it is on far RIGHT generate WM_HSCROLL left message + if (x <= rect.left+2) + { + SendMessage(lpColumnLB->hwndList, (lpColumnLB->fUseVlist) ? VLB_HSCROLL : WM_HSCROLL, MAKEWPARAM(SB_LINEUP, 0), (LPARAM)NULL); + return; + } + +// rect.right -= lpColumnLB->xPos; +// +// // +// // it if is out of the title area, or if it is in the original column +// // +// if ((PtInRect(&lpColumnLB->ColClickRect, Point) == TRUE) || // original column +// (PtInRect(&rect, Point) == FALSE) ) // title area +// { +// // +// // then it has moved back into the original column, switch to +// //COLUMNCLICK mode +// // +// lpColumnLB->fMouseState = MOUSE_COLUMNCLICK; +// +// SetCursor(LoadCursor(0, IDC_ARROW)); +// return; +// } + break; + + case MOUSE_COLUMNCLICK: + // + // if this is a column click, we track the messages until the mouse has moved + // outside of the original column rectangle, if it does this, then we switch to + // COLUMNDRAG mode, until they let go, or until they move back to the original + // column. + // + Point.x = x; + Point.y = y; + + GetClientRect(lpColumnLB->hwndTitleList, &rect); + rect.right -= lpColumnLB->xPos; + + // + // if it is outside of the original column, and inside title area, then swtich to + // DRAG mode + // + if ((PtInRect(&lpColumnLB->ColClickRect, Point) == FALSE) && // + (PtInRect(&rect, Point) == TRUE) ) // title area + { + + // + // then it has moved outside of the column, switch to + //COLUMNDRAG mode + // + lpColumnLB->fMouseState = MOUSE_COLUMNDRAG; + + hCursor = LoadCursor(lpColumnLB->hInstance, TEXT("ColDragCursor")); + SetCursor(hCursor); + } + break; + } +} + + +// ------------------------------------------------------------------ +// ColumnLBClass_OnLButtonUp() +// +// Handles WM_LBUTTONUp messages from the client +// area above the listbox +// +// +// HISTORY: +// Tom Laird-McConnell 5/3/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + + BYTE PhysColumn = lpColumnLB->ColumnOrderTable[lpColumnLB->ColClickStart]; + BYTE PhysSourceColumn; + + int AdjustedX = x - lpColumnLB->xPos; + + POINT Point; + + BYTE NewOrderTable[MAX_COLUMNS]; + + LPBYTE lpNewOrderTable = NewOrderTable; + LPBYTE lpOrderTable = lpColumnLB->ColumnOrderTable; + + + BYTE CurrentCol; + BYTE DestCol; + BYTE SourceCol; + TCHAR Direction; + + BYTE i; + HDC hdc; + RECT rect; + + + SetCursor(LoadCursor(0, IDC_ARROW)); // go back to arrow + + switch (lpColumnLB->fMouseState) + { + case MOUSE_COLUMNRESIZE: + // + // if we were in resize column mode, then resize the column to the left of the border + // + ReleaseCapture(); + ClipCursor(NULL); + + lpColumnLB->fMouseState = 0; + + // clean up line + GetClientRect(hwnd, &rect); + hdc = GetDC(hwnd); + + // massage the value to make sure it's in the right range... + if (AdjustedX < lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]+8) + AdjustedX = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]+8; + + // un invert previous postion + if (lpColumnLB->xPrevPos) + { + rect.left = lpColumnLB->xPrevPos; + rect.right = rect.left+1; + InvertRect(hdc, &rect); + } + + ReleaseDC(hwnd, hdc); + + // + // set the physical column width to be the current x position - the current virtual column offset + // + SendMessage(hwnd, + CLB_SETCOLWIDTH, + (WPARAM)PhysColumn, + (LPARAM)AdjustedX - lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart]); + break; + + case MOUSE_COLUMNDRAG: + + lpColumnLB->fMouseState = 0; + + ReleaseCapture(); + ClipCursor(NULL); + + lpColumnLB->ColumnInfoTable[PhysColumn].fDepressed = FALSE; + + // + // we need to figure out what column we ended up on + // + for(i=1; i < lpColumnLB->nColumns+1; i++) + { + // + // if it fits in this columns area, then this is the destination column + // + if ((AdjustedX > lpColumnLB->ColumnOffsetTable[i-1]) && + (AdjustedX < lpColumnLB->ColumnOffsetTable[i])) + { + // + // make duplicate of the table + // + memcpy(NewOrderTable, lpOrderTable, sizeof(BYTE)*lpColumnLB->nColumns); + + // + // i-1 is the destination column! (virtual) + // + SourceCol = lpColumnLB->ColClickStart; // virtual + DestCol = i-1; // virtual + PhysSourceColumn = lpColumnLB->ColumnOrderTable[SourceCol]; // physical + + Direction = (SourceCol > DestCol) ? -1 : 1; + + CurrentCol = SourceCol; + while (CurrentCol != DestCol) + { + NewOrderTable[CurrentCol] = NewOrderTable[CurrentCol + Direction]; + CurrentCol += Direction; + } + + // + // ok, it's equal to destination, so let's put the source Physical value into the destination + // + NewOrderTable[CurrentCol] = PhysSourceColumn; + + // + // ok, so now set the order to the new order + // + SendMessage(hwnd, CLB_SETCOLORDER, (WPARAM)0, (LPARAM)NewOrderTable); + } + } + + GetClientRect(lpColumnLB->hwndTitleList, &rect); + rect.left = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart] + lpColumnLB->xPos; + rect.right = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart+1] + lpColumnLB->xPos; + InvalidateRect(lpColumnLB->hwndTitleList, &rect, FALSE); + + break; + + case MOUSE_COLUMNCLICK: + // + // if this is a column click, we track the messages until the mouse has moved + // + lpColumnLB->fMouseState = 0; + + ReleaseCapture(); + ClipCursor(NULL); + + lpColumnLB->ColumnInfoTable[PhysColumn].fDepressed = FALSE; + + GetClientRect(lpColumnLB->hwndTitleList, &rect); + rect.left = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart] + lpColumnLB->xPos; + rect.right = lpColumnLB->ColumnOffsetTable[lpColumnLB->ColClickStart+1] + lpColumnLB->xPos; + InvalidateRect(lpColumnLB->hwndTitleList, &rect, FALSE); + + // + // now send a CLBN_SINGLECLICK message to the parent, only if the mousebutton was let up in the original + // column + // + Point.x = AdjustedX; + Point.y = y; + if (PtInRect(&lpColumnLB->ColClickRect, Point) == TRUE) + SendMessage(GetParent(hwnd), CLBN_TITLESINGLECLK, (WPARAM)GetDlgCtrlID(hwnd), (LPARAM)PhysColumn); + return; + } +} + +// ------------------------------------------------------------------ +// ColumnLBClass_OnRButtonDown() +// +// Handles WM_RBUTTON_DOWN messages +// alg: +// +// figure out where we are +// determine listbox item +// find height of rows +// translate mouse Y into a row number +// are we VLIST? +// Yes, Get TopIndex +// are we Owner Draw? +// Yes +// Send message to VLIST to get the data for row number +// No +// item number + TopIndex is the info the parent needs. +// No +// item number is the info the parent needs +// determine column +// calc which column taking into account scrolling +// send message to parent with info +// The parent will receive the column in wParam and the item in lParam. lParam +// needs to be the item because it might be the owner draw data. +// +// +// +// HISTORY: +// Steve Hiskey 10/19/93 Created +// ------------------------------------------------------------------ +void ColumnLBClass_OnRButtonDown (HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) +{ + LPCOLUMNLBSTRUCT lpColumnLB = (LPCOLUMNLBSTRUCT)GetWindowLong(hwnd, 0L); + // get the item height here and not when the OnFont message is + // processed. ?? we get different/wrong results otherwise. + int ItemHeight = (int)ListBox_GetItemHeight(hwnd,1); + int Item = y / ItemHeight; + BYTE i; + int AdjustedX = x - lpColumnLB->xPos; + BYTE VirtColumn; + DWORD TopIndex; + CLBRBUTTONSTRUCT RButtonStruct; + BOOL GotOne = FALSE; + BOOL fTemp; + + + RButtonStruct.x = x; + RButtonStruct.y = y + lpColumnLB->yTitle; + RButtonStruct.hwndChild = hwnd; + + // + // we already have the item (non VList), figure out which column + // + for(i=1; i < lpColumnLB->nColumns+1; i++) + { + if ((AdjustedX > lpColumnLB->ColumnOffsetTable[i-1]) && + (AdjustedX < lpColumnLB->ColumnOffsetTable[i])) + { + // + // we have our column. Get the Physical Column. The parent of this column + // list box know what columns are interesting... and how the physical columns + // map to the virtual columns. + // + VirtColumn = i-1; + RButtonStruct.PhysColumn = lpColumnLB->ColumnOrderTable[VirtColumn]; + GotOne = TRUE; + break; + } + } + if ( !GotOne) + return; + + // are we VLIST? + + if ( lpColumnLB->fUseVlist ) + { + DWORD Style; + + // are we owner draw? If so, then we don't care about TopIndex, we just want + // the instance data + Style = (DWORD)SendMessage(lpColumnLB->hwndList, VLB_GETVLISTSTYLE, 0, 0L); + if ( Style && VLBS_USEDATAVALUES ) + { + // we are use data values. This means that we must ask the VList for the + // data and this is the data is the identifier of the row. ie, the data the + // VList stores is the structure needed to identify and display the line. + + RButtonStruct.Index = ListBox_GetItemData(lpColumnLB->hwndList, Item ); + + } + else + { + // we are a normal vlist box. Get the top index and add our offset + // from top of listbox to it. + + TopIndex = (DWORD)SendMessage(lpColumnLB->hwndList, LB_GETTOPINDEX, 0, 0L); + RButtonStruct.Index = TopIndex + Item; + } + + } + else + { + // we are a normal list box. We need to know what item we are looking at. + // ask the listbox for the top index. + TopIndex = (DWORD)SendMessage(lpColumnLB->hwndList, LB_GETTOPINDEX, 0, 0L); + RButtonStruct.Index = TopIndex + Item; + } + + // if they have hit rButton, we should set the focus to this item (lButton)... since + // WE are providing the CLB_SETCURSEL, we must tell the parent... some weird rule about + // if the user does a set cur sel, then the parent is notified, but if the parent does + // the set cur sel, the parent is not notified... since we are neither the parent or the + // user, we have to do both. + + + // if VLIST, we need to send just the item, top TopIndex + Item... + + if ( lpColumnLB->fUseVlist ) + fTemp = ListBox_SetCurSel(lpColumnLB->hwndList, Item); + else + fTemp = ListBox_SetCurSel(lpColumnLB->hwndList, RButtonStruct.Index); + + if ( fTemp ) + SendMessage(GetParent(hwnd), WM_COMMAND, + GetDlgCtrlID( lpColumnLB->hwndList), + MAKELPARAM(lpColumnLB->hwndList, LBN_SELCHANGE)); + + // we are ready to send which column and which row to the parent. + + SendMessage ( GetParent (hwnd), CLBN_RBUTTONDOWN, (WORD)0, (LONG) &RButtonStruct ); + +} + + + +// ------------------------------------------------------------------ +// ColumnLBClass_DrawColumnBorder() +// +// +// HISTORY: +// Tom Laird-McConnell 3/15/94 created +// ------------------------------------------------------------------ +void ColumnLB_DrawColumnBorder(HDC hDC, RECT *lpRect, int Bottom, HBRUSH hBackgroundBrush) +{ + int ncxBorder = GetSystemMetrics(SM_CXBORDER); + RECT rect; + + CopyRect(&rect, lpRect); + + // fill in left side of rect + rect.right = rect.left; + rect.left -= (WHITESPACE/4); + FillRect(hDC, &rect, hBackgroundBrush); + + // fill in right side of rect + rect.left = lpRect->right; + rect.right = lpRect->right + ncxBorder; + FillRect(hDC, &rect, hBackgroundBrush); + + // draw the line itself + MoveToEx( hDC, rect.right, rect.top, NULL); + LineTo( hDC, rect.right, Bottom); +} + diff --git a/private/nw/convert/nwconv/columnlb.h b/private/nw/convert/nwconv/columnlb.h new file mode 100644 index 000000000..00d024ff4 --- /dev/null +++ b/private/nw/convert/nwconv/columnlb.h @@ -0,0 +1,329 @@ +// ================================================================== +// Copyright 1990-1993 Microsoft corporation +// all rights reservered +// ================================================================== +// +// MODULE: COLUMNLB.H +// PURPOSE: Definitions of all external procedure prototypes for custom +// window class ColumnLB +// +// ------ TABSTOP = 4 ------------------- +// +// HISTORY +// ------- +// Tom Laird-McConnell 5/1/93 Created +// ================================================================== + +#ifndef _COLUMNLB_ +#define _COLUMNLB_ + +#ifdef __cplusplus +extern "C"{ +#endif + +// +// CONTROL STYLES +// +#define CLBS_NOTIFYLMOUSE 0x0200L // pass on WM_LMOUSE messages to perent +#define CLBS_NOTIFYRMOUSE 0x0800L // pass on WM_RMOUSE messages to parent + +// +// CONTROL MESSAGES +// + +#define CLB_BASE (WM_USER+4000) + +#define CLB_MSGMIN (CLB_BASE) + +#define CLB_GETNUMBERCOLS (CLB_BASE+0) // get the number of columns (ret=NumCols) +#define CLB_SETNUMBERCOLS (CLB_BASE+1) // set the number of columns (wparam=NumCols) + +#define CLB_GETCOLWIDTH (CLB_BASE+2) // get a column width (wParm=Column ret=ColWidth in DU's) +#define CLB_SETCOLWIDTH (CLB_BASE+3) // set a column width (wParm=Column lParam=Width) + +#define CLB_GETCOLTITLE (CLB_BASE+4) // get a column's title (wParm=Column, ret=Title) +#define CLB_SETCOLTITLE (CLB_BASE+5) // set a column's title (wParm=Col, lParm=Title) + +#define CLB_GETSORTCOL (CLB_BASE+6) // get the sort column (ret=Col) +#define CLB_SETSORTCOL (CLB_BASE+7) // set the sort column (wParm=Col) + +#define CLB_AUTOWIDTH (CLB_BASE+8) // auto-matically set column widths using titles... + +#define CLB_GETCOLOFFSETS (CLB_BASE+9) // gets the incremental col offsets (ret=LPINT array) +#define CLB_SETCOLOFFSETS (CLB_BASE+10) + +#define CLB_GETCOLORDER (CLB_BASE+11) // get the order that columns should be displayed(ret=LPBYTE table) +#define CLB_SETCOLORDER (CLB_BASE+12) // set the order that columns should be displayed(LParm=LPBYTE TABLE) + +#define CLB_HSCROLL (CLB_BASE+13) // a hscroll event (INTERNAL) + +#define CLB_GETFOCUS (CLB_BASE+14) // get the primary key focus window of CLB + +#define CLB_GETROWCOLTEXT (CLB_BASE+15) // given a row AND a column, give me the text for the physical column. + +#define CLB_GETTEXTPTRS (CLB_BASE+16) // just like gettext, but it give the array of pointers to the strings. + +#define CLB_CHECKFOCUS (CLB_BASE+17) // Does this listbox have the focus? + +/* + * Listbox messages (Defined as CLB_BASE+0+LB_ADDSTRING...to get original LB_ message, just take msg-CLB_BASE to get LB_ + */ + +#define CLB_LISTBOX_MSGMIN (CLB_MSGMIN+LB_ADDSTRING ) + +#define CLB_ADDSTRING (CLB_MSGMIN+LB_ADDSTRING ) +#define CLB_INSERTSTRING (CLB_MSGMIN+LB_INSERTSTRING ) +#define CLB_DELETESTRING (CLB_MSGMIN+LB_DELETESTRING ) +#define CLB_SELITEMRANGEEX (CLB_MSGMIN+LB_SELITEMRANGEEX ) +#define CLB_RESETCONTENT (CLB_MSGMIN+LB_RESETCONTENT ) +#define CLB_SETSEL (CLB_MSGMIN+LB_SETSEL ) +#define CLB_SETCURSEL (CLB_MSGMIN+LB_SETCURSEL ) +#define CLB_GETSEL (CLB_MSGMIN+LB_GETSEL ) +#define CLB_GETCURSEL (CLB_MSGMIN+LB_GETCURSEL ) +#define CLB_GETTEXT (CLB_MSGMIN+LB_GETTEXT ) +#define CLB_GETTEXTLEN (CLB_MSGMIN+LB_GETTEXTLEN ) +#define CLB_GETCOUNT (CLB_MSGMIN+LB_GETCOUNT ) +#define CLB_SELECTSTRING (CLB_MSGMIN+LB_SELECTSTRING ) +#define CLB_DIR (CLB_MSGMIN+LB_DIR ) +#define CLB_GETTOPINDEX (CLB_MSGMIN+LB_GETTOPINDEX ) +#define CLB_FINDSTRING (CLB_MSGMIN+LB_FINDSTRING ) +#define CLB_GETSELCOUNT (CLB_MSGMIN+LB_GETSELCOUNT ) +#define CLB_GETSELITEMS (CLB_MSGMIN+LB_GETSELITEMS ) +#define CLB_SETTABSTOPS (CLB_MSGMIN+LB_SETTABSTOPS ) +#define CLB_GETHORIZONTALEXTENT (CLB_MSGMIN+LB_GETHORIZONTALEXTENT) +#define CLB_SETHORIZONTALEXTENT (CLB_MSGMIN+LB_SETHORIZONTALEXTENT) +#define CLB_SETCOLUMNWIDTH (CLB_MSGMIN+LB_SETCOLUMNWIDTH ) +#define CLB_ADDFILE (CLB_MSGMIN+LB_ADDFILE ) +#define CLB_SETTOPINDEX (CLB_MSGMIN+LB_SETTOPINDEX ) +#define CLB_GETITEMRECT (CLB_MSGMIN+LB_GETITEMRECT ) +#define CLB_GETITEMDATA (CLB_MSGMIN+LB_GETITEMDATA ) +#define CLB_SETITEMDATA (CLB_MSGMIN+LB_SETITEMDATA ) +#define CLB_SELITEMRANGE (CLB_MSGMIN+LB_SELITEMRANGE ) +#define CLB_SETANCHORINDEX (CLB_MSGMIN+LB_SETANCHORINDEX ) +#define CLB_GETANCHORINDEX (CLB_MSGMIN+LB_GETANCHORINDEX ) +#define CLB_SETCARETINDEX (CLB_MSGMIN+LB_SETCARETINDEX ) +#define CLB_GETCARETINDEX (CLB_MSGMIN+LB_GETCARETINDEX ) +#define CLB_SETITEMHEIGHT (CLB_MSGMIN+LB_SETITEMHEIGHT ) +#define CLB_GETITEMHEIGHT (CLB_MSGMIN+LB_GETITEMHEIGHT ) +#define CLB_FINDSTRINGEXACT (CLB_MSGMIN+LB_FINDSTRINGEXACT ) +#define CLB_SETLOCALE (CLB_MSGMIN+LB_SETLOCALE ) +#define CLB_GETLOCALE (CLB_MSGMIN+LB_GETLOCALE ) +#define CLB_SETCOUNT (CLB_MSGMIN+LB_SETCOUNT ) + +#define CLB_LISTBOX_MSGMAX CLB_SETCOUNT + +#define CLB_MSGMAX CLB_LISTBOX_MSGMAX + + +// +// NOTIFICATION MESSAGES +// +#define CLBN_MSGMIN (CLB_MSGMAX + 1) + +#define CLBN_DRAWITEM CLBN_MSGMIN // ask the parent to do a XXXXitem lParam = LPDRAWITEMSTRUCT) +//#define CLBN_COMPAREITEM CLBN_MSGMIN+2) // ask the parent to do a XXXXitem (wParam=PhysCol, lParam = LPCOMPAREITEMSTRUCT) +#define CLBN_CHARTOITEM (CLBN_MSGMIN+3) // ask the parent to do a XXXXitem (wParam=PhysCol, ) + +#define CLBN_TITLESINGLECLK (CLBN_MSGMIN+4) // notify the parent that a user clicked on a title (wParam = CTLID, lParam=Col) +#define CLBN_TITLEDBLCLK (CLBN_MSGMIN+5) // notify the parent that a user double-clicked on a title (wParam = CTLID, lParam=Col) + +#define CLBN_COLREORDER (CLBN_MSGMIN+6) // notify the parent that someone changed the column order (LPARAM=LPINT order) +#define CLBN_COLSIZE (CLBN_MSGMIN+7) // notify the parent that someone changed the column size (lParam=LPINT widths) +#define CLBN_RBUTTONDOWN (CLBN_MSGMIN+8) // notify the parent on rbutton which row and column +#define CLBN_RBUTTONUP (CLBN_MSGMIN+9) // notify the parent on rbutton which row and column + +#define CLBN_MSGMAX CLBN_RBUTTONUP + + +#define MAX_COLUMNS 32 + + +// +// structure used to keep track of column info +// +typedef struct _ColumnInfo +{ + int Width; // width in LU's of column + LPTSTR lpTitle; // pointer to title string + BOOL fDepressed; // flag for whether this columns header button is depressed or not +} COLUMNINFO; +typedef COLUMNINFO *LPCOLUMNINFO; + + +// +// structure used for doing a Column DrawItem +// +typedef struct _CLBDrawItemStruct +{ + DRAWITEMSTRUCT DrawItemStruct; + LPBYTE lpColOrder; + DWORD nColumns; + RECT rect[MAX_COLUMNS]; +} CLBDRAWITEMSTRUCT; +typedef CLBDRAWITEMSTRUCT *LPCLBDRAWITEMSTRUCT; + +#define MOUSE_COLUMNDRAG 1 +#define MOUSE_COLUMNRESIZE 2 +#define MOUSE_COLUMNCLICK 3 + +// +// internal datastructure used to keep track of everything internal to the +// ColumnLB class... +// +typedef struct _ColumnLBstruct +{ + DWORD Style; // style of columnlb + + HWND hwndList; // handle to the internal listbox + HWND hwndTitleList; // handle to title listbox + + HFONT hFont; // font in use... + + HINSTANCE hInstance; // hInstance of the app which created this + + BYTE nColumns; // number of columns in the column listbox + COLUMNINFO ColumnInfoTable[MAX_COLUMNS]; // table of ColumnInfoStructures + int ColumnOffsetTable[MAX_COLUMNS]; // table of offsets from front of listbox (in lu's) + BYTE ColumnOrderTable[MAX_COLUMNS]; // indexes of columns in order of display + BYTE SortColumn; // index of current sort column + + int xPos; // current x position in scroll-box + int yTitle; // height of title portion... + + FARPROC OldListboxProc; // old listbox proc + FARPROC NewListboxProc; // New listbox proc + + FARPROC OldTitleListboxProc; // old listbox proc + FARPROC NewTitleListboxProc; // New listbox proc + + BYTE fUseVlist:1; // flag for whether to use VLIST class or not... + BYTE fMouseState:3; // state for moving + BYTE fSorting:1; // flag to signifiy that we are sorting so ignore DELETEITEM's + BYTE fHasFocus:1; // does the listbox have the focus? + + int xPrevPos ; // previous x mouse position + BYTE ColClickStart; // column of click start + RECT ColClickRect; // rect of click column +} COLUMNLBSTRUCT; +typedef COLUMNLBSTRUCT FAR *LPCOLUMNLBSTRUCT; + +#define COLUMNLBCLASS_CLASSNAME TEXT("ColumnListBox") // normal Column listbox +#define COLUMNVLBCLASS_CLASSNAME TEXT("ColumnVListBox") // Vlist Column box + +// +// structure used for RBUTTONDOWN messages. The Column list box tells the parent +// which column and index. +// +typedef struct _CLBRButtonStruct +{ + HWND hwndChild; + BYTE PhysColumn; + DWORD Index; + int x; + int y; +} CLBRBUTTONSTRUCT; + +typedef CLBRBUTTONSTRUCT *LPCLBRBUTTONSTRUCT; + + +// +// function prototypes +// +BOOL ColumnLBClass_Register(HINSTANCE hInstance); +BOOL ColumnVLBClass_Register(HINSTANCE hInstance); +BOOL ColumnLBClass_Unregister(HINSTANCE hInstance); +BOOL ColumnVLBClass_Unregister(HINSTANCE hInstance); + +void ColumnLB_DrawColumnBorder(HDC hdc, RECT *rect, int Bottom, HBRUSH hBrush); + +// ----------------------------------------------------------------------------------- +// +// ColumnListBox_ Macros (uses CLB_ messages) New definitions +// +#define ColumnLB_GetNumberCols(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETNUMBERCOLS, 0L, (LPARAM)0)) +#define ColumnLB_SetNumberCols(hwndCtl,Number) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETNUMBERCOLS, (WPARAM)Number, (LPARAM)0)) +#define ColumnLB_GetColWidth(hwndCtl,Column) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETCOLWIDTH, (WPARAM)Column, (LPARAM)0)) +#define ColumnLB_SetColWidth(hwndCtl,Column, Width) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETCOLWIDTH, (WPARAM)Column, (LPARAM)Width)) +#define ColumnLB_GetColTitle(hwndCtl,Column) ((LPTSTR)(DWORD)SendMessage((hwndCtl), CLB_GETCOLTITLE, (WPARAM)Column, (LPARAM)0)) +#define ColumnLB_SetColTitle(hwndCtl,Column, Title) ((LPTSTR)(DWORD)SendMessage((hwndCtl), CLB_SETCOLTITLE, (WPARAM)Column, (LPARAM)Title)) +#define ColumnLB_GetSortCol(hwndCtl) ((DWORD)SendMessage((hwndCtl), CLB_GETSORTCOL, (WPARAM)0, (LPARAM)0)) +#define ColumnLB_SetSortCol(hwndCtl,Column) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETSORTCOL, (WPARAM)Column, (LPARAM)0)) +#define ColumnLB_AutoWidth(hwndCtl, Width) ((int)(DWORD)SendMessage((hwndCtl), CLB_AUTOWIDTH, (WPARAM)Width, (LPARAM)0)) +#define ColumnLB_GetColOffsets(hwndCtl) ((LPINT)(DWORD)SendMessage((hwndCtl), CLB_GETCOLOFFSETS, (WPARAM)0, (LPARAM)0)) +#define ColumnLB_SetColOffsets(hwndCtl,Offsets) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETCOLOFFSETS, (WPARAM)Offsets, (LPARAM)0)) +#define ColumnLB_GetColOrder(hwndCtl) ((LPBYTE)(DWORD)SendMessage((hwndCtl), CLB_GETCOLORDER, (WPARAM)0, (LPARAM)0)) +#define ColumnLB_SetColOrder(hwndCtl, Order) ((LPBYTE)(DWORD)SendMessage((hwndCtl), CLB_SETCOLORDER, (WPARAM)0, (LPARAM)Order)) +#define ColumnLB_CheckFocus(hwndCtl) ((BOOL)(DWORD)SendMessage((hwndCtl), CLB_CHECKFOCUS, (WPARAM)0, (LPARAM)0)) + +// ----------------------------------------------------------------------------------- +// +// ColumnListBox_ Macros (uses CLB_ messages) Listbox definitions +// +#define ColumnLB_Enable(hwndCtl, fEnable) EnableWindow((hwndCtl), (fEnable)) + +#define ColumnLB_GetCount(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETCOUNT, 0L, 0L)) +#define ColumnLB_ResetContent(hwndCtl) ((BOOL)(DWORD)SendMessage((hwndCtl), CLB_RESETCONTENT, 0L, 0L)) + +#define ColumnLB_AddString(hwndCtl, lpsz) ((int)(DWORD)SendMessage((hwndCtl), CLB_ADDSTRING, 0L, (LPARAM)(LPCTSTR)(lpsz))) +#define ColumnLB_InsertString(hwndCtl, index, lpsz) ((int)(DWORD)SendMessage((hwndCtl), CLB_INSERTSTRING, (WPARAM)(int)(index), (LPARAM)(LPCTSTR)(lpsz))) + +#define ColumnLB_AddItemData(hwndCtl, data) ((int)(DWORD)SendMessage((hwndCtl), CLB_ADDSTRING, 0L, (LPARAM)(data))) +#define ColumnLB_InsertItemData(hwndCtl, index, data) ((int)(DWORD)SendMessage((hwndCtl), CLB_INSERTSTRING, (WPARAM)(int)(index), (LPARAM)(data))) + +#define ColumnLB_DeleteString(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_DELETESTRING, (WPARAM)(int)(index), 0L)) + +#define ColumnLB_GetTextLen(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETTEXTLEN, (WPARAM)(int)(index), 0L)) +#define ColumnLB_GetText(hwndCtl, index, lpszBuffer) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETTEXT, (WPARAM)(int)(index), (LPARAM)(LPCTSTR)(lpszBuffer))) +#define ColumnLB_GetTextPtrs(hwndCtl, index) ((LPTSTR *)(DWORD)SendMessage((hwndCtl), CLB_GETTEXTPTRS, (WPARAM)(int)(index), (LPARAM)0)) +#define ColumnLB_GetRowColText(hwndCtl, index, col) (LPBYTE)(DWORD)SendMessage((hwndCtl), CLB_GETROWCOLTEXT, (WPARAM)(int) (col), (LPARAM)(int)(index)) + +#define ColumnLB_GetItemData(hwndCtl, index) ((LRESULT)(DWORD)SendMessage((hwndCtl), CLB_GETITEMDATA, (WPARAM)(int)(index), 0L)) +#define ColumnLB_SetItemData(hwndCtl, index, data) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETITEMDATA, (WPARAM)(int)(index), (LPARAM)(data))) + +#if (WINVER >= 0x030a) +#define ColumnLB_FindString(hwndCtl, indexStart, lpszFind) ((int)(DWORD)SendMessage((hwndCtl), CLB_FINDSTRING, (WPARAM)(int)(indexStart), (LPARAM)(LPCTSTR)(lpszFind))) +#define ColumnLB_FindItemData(hwndCtl, indexStart, data) ((int)(DWORD)SendMessage((hwndCtl), CLB_FINDSTRING, (WPARAM)(int)(indexStart), (LPARAM)(data))) + +#define ColumnLB_SetSel(hwndCtl, fSelect, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETSEL, (WPARAM)(BOOL)(fSelect), (LPARAM)(index))) +#define ColumnLB_SelItemRange(hwndCtl, fSelect, first, last) ((int)(DWORD)SendMessage((hwndCtl), CLB_SELITEMRANGE, (WPARAM)(BOOL)(fSelect), MAKELPARAM((first), (last)))) + +#define ColumnLB_GetCurSel(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETCURSEL, 0L, 0L)) +#define ColumnLB_SetCurSel(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETCURSEL, (WPARAM)(int)(index), 0L)) + +#define ColumnLB_SelectString(hwndCtl, indexStart, lpszFind) ((int)(DWORD)SendMessage((hwndCtl), CLB_SELECTSTRING, (WPARAM)(int)(indexStart), (LPARAM)(LPCTSTR)(lpszFind))) +#define ColumnLB_SelectItemData(hwndCtl, indexStart, data) ((int)(DWORD)SendMessage((hwndCtl), CLB_SELECTSTRING, (WPARAM)(int)(indexStart), (LPARAM)(data))) + +#define ColumnLB_GetSel(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETSEL, (WPARAM)(int)(index), 0L)) +#define ColumnLB_GetSelCount(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETSELCOUNT, 0L, 0L)) +#define ColumnLB_GetTopIndex(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETTOPINDEX, 0L, 0L)) +#define ColumnLB_GetSelItems(hwndCtl, cItems, lpItems) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETSELITEMS, (WPARAM)(int)(cItems), (LPARAM)(int *)(lpItems))) + +#define ColumnLB_SetTopIndex(hwndCtl, indexTop) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETTOPINDEX, (WPARAM)(int)(indexTop), 0L)) + +#define ColumnLB_SetColumnWidth(hwndCtl, cxColumn) ((void)SendMessage((hwndCtl), CLB_SETCOLUMNWIDTH, (WPARAM)(int)(cxColumn), 0L)) +#define ColumnLB_GetHorizontalExtent(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETHORIZONTALEXTENT, 0L, 0L)) +#define ColumnLB_SetHorizontalExtent(hwndCtl, cxExtent) ((void)SendMessage((hwndCtl), CLB_SETHORIZONTALEXTENT, (WPARAM)(int)(cxExtent), 0L)) + +#define ColumnLB_SetTabStops(hwndCtl, cTabs, lpTabs) ((BOOL)(DWORD)SendMessage((hwndCtl), CLB_SETTABSTOPS, (WPARAM)(int)(cTabs), (LPARAM)(int *)(lpTabs))) + +#define ColumnLB_GetItemRect(hwndCtl, index, lprc) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETITEMRECT, (WPARAM)(int)(index), (LPARAM)(RECT *)(lprc))) + +#define ColumnLB_SetCaretIndex(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETCARETINDEX, (WPARAM)(int)(index), 0L)) +#define ColumnLB_GetCaretIndex(hwndCtl) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETCARETINDEX, 0L, 0L)) + +#define ColumnLB_FindStringExact(hwndCtl, indexStart, lpszFind) ((int)(DWORD)SendMessage((hwndCtl), CLB_FINDSTRINGEXACT, (WPARAM)(int)(indexStart), (LPARAM)(LPCTSTR)(lpszFind))) + +#define ColumnLB_SetItemHeight(hwndCtl, index, cy) ((int)(DWORD)SendMessage((hwndCtl), CLB_SETITEMHEIGHT, (WPARAM)(int)(index), MAKELPARAM((cy), 0))) +#define ColumnLB_GetItemHeight(hwndCtl, index) ((int)(DWORD)SendMessage((hwndCtl), CLB_GETITEMHEIGHT, (WPARAM)(int)(index), 0L)) +#endif /* WINVER >= 0x030a */ + +#define ColumnLB_Dir(hwndCtl, attrs, lpszFileSpec) ((int)(DWORD)SendMessage((hwndCtl), CLB_DIR, (WPARAM)(UINT)(attrs), (LPARAM)(LPCTSTR)(lpszFileSpec))) + +#define ColumnLB_GetFocus(hwndCtl) ((HWND)(DWORD)SendMessage((hwndCtl), CLB_GETFOCUS, 0L, 0L)) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/constant.h b/private/nw/convert/nwconv/constant.h new file mode 100644 index 000000000..9179fa067 --- /dev/null +++ b/private/nw/convert/nwconv/constant.h @@ -0,0 +1,36 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _CONSTANT_ +#define _CONSTANT_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#define MAX_NW_OBJECT_NAME_LEN 48 +#define MAX_NT_SERVER_NAME_LEN 15 + +// These constants are just a safe max of the NT and NW constants +#define MAX_SERVER_NAME_LEN 48 +#define MAX_USER_NAME_LEN 256 // must add room for nw4 names... +#define MAX_NT_USER_NAME_LEN 20 +#define MAX_SHARE_NAME_LEN 16 +#define MAX_GROUP_NAME_LEN 50 +#define MAX_NT_GROUP_NAME_LEN 20 +#define MAX_DOMAIN_NAME_LEN 15 +#define MAX_UNC_PATH MAX_PATH + MAX_SERVER_NAME_LEN + MAX_SHARE_NAME_LEN + 265 + +#define MAX_PW_LEN 14 +#define MAX_UCONST_LEN 10 +#define MAX_DOMAIN_LEN 15 + +#define TMP_STR_LEN_256 256 +#define TMP_STR_LEN_80 80 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/convapi.h b/private/nw/convert/nwconv/convapi.h new file mode 100644 index 000000000..64ab3f954 --- /dev/null +++ b/private/nw/convert/nwconv/convapi.h @@ -0,0 +1,29 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HCONVAPI_ +#define _HCONVAPI_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "netutil.h" +#include "filesel.h" +#include "servlist.h" +void TreeRecurseCurrentShareSet(SHARE_BUFFER *CShare); +void TreeRootInit(SHARE_BUFFER *CShare, LPTSTR NewPath); +void TreeFillRecurse(UINT Level, LPTSTR Path, DIR_BUFFER *Dir); +ULONG TotalFileSizeGet(); +void FileSelect_Do(HWND hDlg, SOURCE_SERVER_BUFFER *SourceServ, SHARE_BUFFER *CShare); +#include "sbrowse.h" +#include "statbox.h" + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/private/nw/convert/nwconv/ctlspriv.h b/private/nw/convert/nwconv/ctlspriv.h new file mode 100644 index 000000000..34a681f34 --- /dev/null +++ b/private/nw/convert/nwconv/ctlspriv.h @@ -0,0 +1,172 @@ +#define STRICT + +/* disable "non-standard extension" warnings in our code +#ifndef RC_INVOKED +#pragma warning(disable:4001) +#endif + */ + +#include +#include +//#include + +#define OFFSETOF(x) x +#define Static + +#define UNICODE_FONT_NAME TEXT("Lucida Sans Unicode") +#define COUNTOF(x) (sizeof(x)/sizeof(*x)) +#define ByteCountOf(x) ((x) * sizeof(TCHAR)) +#define LONG2POINT(l, pt) ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l)) + +#include + +extern HINSTANCE hInst; + +BOOL FAR PASCAL InitToolbarClass(HINSTANCE hInstance); + +BOOL FAR PASCAL InitStatusClass(HINSTANCE hInstance); + +BOOL FAR PASCAL InitHeaderClass(HINSTANCE hInstance); + +BOOL FAR PASCAL InitButtonListBoxClass(HINSTANCE hInstance); + +BOOL FAR PASCAL InitTrackBar(HINSTANCE hInstance); + +BOOL FAR PASCAL InitUpDownClass(HINSTANCE hInstance); + +void FAR PASCAL NewSize(HWND hWnd, int nClientHeight, LONG style, + int left, int top, int width, int height); + +#define IDS_SPACE 0x0400 + +/* System MenuHelp + */ +#define MH_SYSMENU (0x8000 - MINSYSCOMMAND) +#define IDS_SYSMENU (MH_SYSMENU-16) +#define IDS_HEADER (MH_SYSMENU-15) +#define IDS_HEADERADJ (MH_SYSMENU-14) +#define IDS_TOOLBARADJ (MH_SYSMENU-13) + +/* Cursor ID's + */ +#define IDC_SPLIT 100 +#define IDC_MOVEBUTTON 102 + +#define IDC_STOP 103 +#define IDC_COPY 104 +#define IDC_MOVE 105 + +/* Icon ID's + */ +#define IDI_INSERT 150 + +/* AdjustDlgProc stuff + */ +#define ADJUSTDLG 200 +#define IDC_BUTTONLIST 201 +#define IDC_RESET 202 +#define IDC_CURRENT 203 +#define IDC_REMOVE 204 +#define IDC_MOVEUP 205 +#define IDC_MOVEDOWN 206 + +/* bitmap IDs + */ + +#define IDB_THUMB 300 + +/* These are the internal structures used for a status bar. The header + * bar code needs this also + */ +typedef struct tagSTRINGINFO +{ + LPTSTR pString; + UINT uType; + int right; +} STRINGINFO, *PSTRINGINFO; + +typedef struct tagSTATUSINFO +{ + HFONT hStatFont; + BOOL bDefFont; + + int nFontHeight; + int nMinHeight; + int nBorderX, nBorderY, nBorderPart; + + STRINGINFO sSimple; + + int nParts; + STRINGINFO sInfo[1]; + +} STATUSINFO, *PSTATUSINFO; + +#define GWL_PSTATUSINFO 0 /* Window word index for status info */ +#define SBT_NOSIMPLE 0x00ff /* Flags to indicate normal status bar */ + +/* This is the default status bar face name + */ +extern TCHAR szSansSerif[]; + +/* Note that window procedures in protect mode only DLL's may be called + * directly. + */ +void FAR PASCAL PaintStatusWnd(HWND hWnd, PSTATUSINFO pStatusInfo, + PSTRINGINFO pStringInfo, int nParts, int nBorderX, BOOL bHeader); +LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, + LPARAM lParam); + +/* toolbar.c */ +#define GWL_PTBSTATE 0 + +typedef struct tagTBBMINFO /* info for recreating the bitmaps */ +{ + int nButtons; + HINSTANCE hInst; + WORD wID; + HBITMAP hbm; + +} TBBMINFO, NEAR *PTBBMINFO; + +typedef struct tagTBSTATE /* instance data for toolbar window */ +{ + PTBBUTTON pCaptureButton; + HWND hdlgCust; + HWND hwndCommand; + int nBitmaps; + PTBBMINFO pBitmaps; + int iNumButtons; + int nSysColorChanges; + TBBUTTON Buttons[1]; + +} TBSTATE, NEAR *PTBSTATE; + +extern HBITMAP FAR PASCAL SelectBM(HDC hDC, PTBSTATE pTBState, int nButton); +extern void FAR PASCAL DrawButton(HDC hdc, int x, int y, int dx, int dy, + PTBSTATE pTBState, PTBBUTTON ptButton); +extern int FAR PASCAL TBHitTest(PTBSTATE pTBState, int xPos, int yPos); +extern int FAR PASCAL PositionFromID(PTBSTATE pTBState, int id); + +/* tbcust.c */ +extern BOOL FAR PASCAL SaveRestore(HWND hWnd, PTBSTATE pTBState, BOOL bWrite, + LPTSTR FAR *lpNames); +extern void FAR PASCAL CustomizeTB(HWND hWnd, PTBSTATE pTBState, int iPos); +extern void FAR PASCAL MoveButton(HWND hwndToolbar, PTBSTATE pTBState, + int nSource); + + +/* cutils.c */ +void FAR PASCAL NewSize(HWND hWnd, int nHeight, LONG style, int left, int top, int width, int height); +BOOL FAR PASCAL CreateDitherBrush(BOOL bIgnoreCount); /* creates hbrDither */ +BOOL FAR PASCAL FreeDitherBrush(void); +void FAR PASCAL CreateThumb(BOOL bIgnoreCount); +void FAR PASCAL DestroyThumb(void); +void FAR PASCAL CheckSysColors(void); + +extern HBRUSH hbrDither; +extern HBITMAP hbmThumb; +extern int nSysColorChanges; +extern DWORD rgbFace; // globals used a lot +extern DWORD rgbShadow; +extern DWORD rgbHilight; +extern DWORD rgbFrame; diff --git a/private/nw/convert/nwconv/debug.c b/private/nw/convert/nwconv/debug.c new file mode 100644 index 000000000..0a883f8c6 --- /dev/null +++ b/private/nw/convert/nwconv/debug.c @@ -0,0 +1,459 @@ + +#define DUMP // leave enabled... + +#include "globals.h" +#include "switches.h" +#include +#include +#include +#include +#include + +#if DBG +void __cdecl dprintf(LPTSTR szFormat, ...) { + static TCHAR tmpStr[1024]; + va_list marker; + + va_start(marker, szFormat); + wvsprintf(tmpStr, szFormat, marker); + OutputDebugString(tmpStr); + va_end(marker); + +} // dprintf + +BOOL fDoEntireList = FALSE; + +void DumpConvertList(CONVERT_LIST *pConvertList) +{ + if (pConvertList) + { + dprintf( + TEXT("+++CONVERT_LIST(0x%08lx)"), + pConvertList + ); + + dprintf( + TEXT("\r\n\tnext = 0x%08lx") + TEXT("\r\n\tprev = 0x%08lx") + TEXT("\r\n\tSourceServ = 0x%08lx") + TEXT("\r\n\tFileServ = 0x%08lx") + TEXT("\r\n\tConvertOptions = 0x%08lx") + TEXT("\r\n\tFileOptions = 0x%08lx\r\n"), + pConvertList->next, + pConvertList->prev, + pConvertList->SourceServ, + pConvertList->FileServ, + pConvertList->ConvertOptions, + pConvertList->FileOptions + ); + + if (pConvertList->SourceServ) + DumpSourceServerBuffer(pConvertList->SourceServ); + + if (pConvertList->FileServ) + DumpDestServerBuffer(pConvertList->FileServ); + + if (fDoEntireList && pConvertList->next) + DumpConvertList(pConvertList->next); + + dprintf( + TEXT("---CONVERT_LIST(0x%08lx)\r\n"), + pConvertList + ); + } + else + dprintf(TEXT("Null pConvertList\r\n")); + +} // DumpConvertList + + +void DumpDestServerBuffer(DEST_SERVER_BUFFER *pDestServerBuffer) +{ + if (pDestServerBuffer) + { + dprintf( + TEXT("+++DEST_SERVER_BUFFER(0x%08lx)"), + pDestServerBuffer + ); + + dprintf( + TEXT("\r\n\tnext = 0x%08lx") + TEXT("\r\n\tprev = 0x%08lx") + TEXT("\r\n\tIndex = 0x%08lx") + TEXT("\r\n\tType = 0x%08lx") + TEXT("\r\n\tVerMaj = 0x%08lx") + TEXT("\r\n\tVerMin = 0x%08lx") + TEXT("\r\n\tLName = %s") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tShareList = 0x%08lx") + TEXT("\r\n\tNumVShares = 0x%08lx") + TEXT("\r\n\tVShareStart = 0x%08lx") + TEXT("\r\n\tVShareEnd = 0x%08lx") + TEXT("\r\n\tUseCount = 0x%08lx") + TEXT("\r\n\tIsNTAS = 0x%08lx") + TEXT("\r\n\tIsFPNW = 0x%08lx") + TEXT("\r\n\tInDomain = 0x%08lx") + TEXT("\r\n\tDomain = 0x%08lx") + TEXT("\r\n\tDriveList = 0x%08lx\r\n"), + pDestServerBuffer->next, + pDestServerBuffer->prev, + pDestServerBuffer->Index, + pDestServerBuffer->Type, + pDestServerBuffer->VerMaj, + pDestServerBuffer->VerMin, + pDestServerBuffer->LName, + pDestServerBuffer->Name, + pDestServerBuffer->ShareList, + pDestServerBuffer->NumVShares, + pDestServerBuffer->VShareStart, + pDestServerBuffer->VShareEnd, + pDestServerBuffer->UseCount, + pDestServerBuffer->IsNTAS, + pDestServerBuffer->IsFPNW, + pDestServerBuffer->InDomain, + pDestServerBuffer->Domain, + pDestServerBuffer->DriveList + ); + + if (pDestServerBuffer->DriveList) + DumpDriveList(pDestServerBuffer->DriveList); + + if (pDestServerBuffer->ShareList) + DumpShareList(pDestServerBuffer->ShareList); + + if (pDestServerBuffer->VShareStart) + DumpVirtualShareBuffer(pDestServerBuffer->VShareStart); + + if (pDestServerBuffer->Domain) + DumpDomainBuffer(pDestServerBuffer->Domain); + + if (fDoEntireList && pDestServerBuffer->next) + DumpDestServerBuffer(pDestServerBuffer->next); + + dprintf( + TEXT("---DEST_SERVER_BUFFER(0x%08lx)\r\n"), + pDestServerBuffer + ); + } + else + dprintf(TEXT("Null pDestServerBuffer\r\n")); + +} // DumpDestServerBuffer + + +void DumpSourceServerBuffer(SOURCE_SERVER_BUFFER *pSourceServerBuffer) +{ + if (pSourceServerBuffer) + { + dprintf( + TEXT("+++SOURCE_SERVER_BUFFER(0x%08lx)"), + pSourceServerBuffer + ); + + dprintf( + TEXT("\r\n\tnext = 0x%08lx") + TEXT("\r\n\tprev = 0x%08lx") + TEXT("\r\n\tIndex = 0x%08lx") + TEXT("\r\n\tType = 0x%08lx") + TEXT("\r\n\tVerMaj = 0x%08lx") + TEXT("\r\n\tVerMin = 0x%08lx") + TEXT("\r\n\tLName = %s") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tShareList = 0x%08lx\r\n"), + pSourceServerBuffer->next, + pSourceServerBuffer->prev, + pSourceServerBuffer->Index, + pSourceServerBuffer->Type, + pSourceServerBuffer->VerMaj, + pSourceServerBuffer->VerMin, + pSourceServerBuffer->LName, + pSourceServerBuffer->Name, + pSourceServerBuffer->ShareList + ); + + if (pSourceServerBuffer->ShareList) + DumpShareList(pSourceServerBuffer->ShareList); + + if (fDoEntireList && pSourceServerBuffer->next) + DumpSourceServerBuffer(pSourceServerBuffer->next); + + dprintf( + TEXT("---SOURCE_SERVER_BUFFER(0x%08lx)\r\n"), + pSourceServerBuffer + ); + } + else + dprintf(TEXT("Null pSourceServerBuffer\r\n")); + +} // DumpSourceServerBuffer + + +void DumpDomainBuffer(DOMAIN_BUFFER *pDomainBuffer) +{ + if (pDomainBuffer) + { + dprintf( + TEXT("+++DOMAIN_BUFFER(0x%08lx)"), + pDomainBuffer + ); + + dprintf( + TEXT("\r\n\tnext = 0x%08lx") + TEXT("\r\n\tprev = 0x%08lx") + TEXT("\r\n\tIndex = 0x%08lx") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tPDCName = %s") + TEXT("\r\n\tType = 0x%08lx") + TEXT("\r\n\tVerMaj = 0x%08lx") + TEXT("\r\n\tVerMin = 0x%08lx") + TEXT("\r\n\tUseCount = 0x%08lx\r\n"), + pDomainBuffer->next, + pDomainBuffer->prev, + pDomainBuffer->Index, + pDomainBuffer->Name, + pDomainBuffer->PDCName, + pDomainBuffer->Type, + pDomainBuffer->VerMaj, + pDomainBuffer->VerMin, + pDomainBuffer->UseCount + ); + + if (fDoEntireList && pDomainBuffer->next) + DumpDomainBuffer(pDomainBuffer->next); + + dprintf( + TEXT("---DOMAIN_BUFFER(0x%08lx)\r\n"), + pDomainBuffer + ); + } + else + dprintf(TEXT("Null pDomainBuffer\r\n")); + +} // DumpDomainBuffer + + +void DumpVirtualShareBuffer(VIRTUAL_SHARE_BUFFER *pVirtualShareBuffer) +{ + if (pVirtualShareBuffer) + { + dprintf( + TEXT("+++VIRTUAL_SHARE_BUFFER(0x%08lx)"), + pVirtualShareBuffer + ); + + dprintf( + TEXT("\r\n\tVFlag = 0x%08lx") + TEXT("\r\n\tnext = 0x%08lx") + TEXT("\r\n\tprev = 0x%08lx") + TEXT("\r\n\tIndex = 0x%08lx") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tUseCount = 0x%08lx") + TEXT("\r\n\tPath = %s") + TEXT("\r\n\tDrive = 0x%08lx\r\n"), + pVirtualShareBuffer->VFlag, + pVirtualShareBuffer->next, + pVirtualShareBuffer->prev, + pVirtualShareBuffer->Index, + pVirtualShareBuffer->Name, + pVirtualShareBuffer->UseCount, + pVirtualShareBuffer->Path, + pVirtualShareBuffer->Drive + ); + + if (pVirtualShareBuffer->Drive) + DumpDriveBuffer(pVirtualShareBuffer->Drive); + + if (fDoEntireList && pVirtualShareBuffer->next) + DumpVirtualShareBuffer(pVirtualShareBuffer->next); + + dprintf( + TEXT("---VIRTUAL_SHARE_BUFFER(0x%08lx)\r\n"), + pVirtualShareBuffer + ); + } + else + dprintf(TEXT("Null pVirtualShareBuffer\r\n")); + +} // DumpVirtualShareBuffer + + +void DumpShareList(SHARE_LIST *pShareList) +{ + ULONG index; + if (pShareList) + { + dprintf( + TEXT(">>>SHARE_LIST(0x%08lx)(%d entries, %d converting, %s)\r\n"), + pShareList, + pShareList->Count, + pShareList->ConvertCount, + pShareList->Fixup ? TEXT("FIXUP") : TEXT("NO FIXUP") + ); + for (index = 0; index < pShareList->Count; index++ ) + DumpShareBuffer(&pShareList->SList[index]); + } + else + dprintf(TEXT("Null pShareList\r\n")); + +} // DumpShareList + + +void DumpShareBuffer(SHARE_BUFFER *pShareBuffer) +{ + if (pShareBuffer) + { + dprintf( + TEXT("+++SHARE_BUFFER(0x%08lx)"), + pShareBuffer + ); + + dprintf( + TEXT("\r\n\tVFlag = 0x%08lx") + TEXT("\r\n\tIndex = 0x%08lx") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tConvert = 0x%08lx") + TEXT("\r\n\tHiddenFiles = 0x%08lx") + TEXT("\r\n\tSystemFiles = 0x%08lx") + TEXT("\r\n\tToFat = 0x%08lx") + TEXT("\r\n\tRoot = 0x%08lx") + TEXT("\r\n\tDrive = 0x%08lx") + TEXT("\r\n\tSize = 0x%08lx") + TEXT("\r\n\tPath = %s") + TEXT("\r\n\tSubDir = %s") + TEXT("\r\n\tVirtual = 0x%08lx") + TEXT("\r\n\tDestShare = 0x%08lx\r\n"), + pShareBuffer->VFlag, + pShareBuffer->Index, + pShareBuffer->Name, + pShareBuffer->Convert, + pShareBuffer->HiddenFiles, + pShareBuffer->SystemFiles, + pShareBuffer->ToFat, + pShareBuffer->Root, + pShareBuffer->Drive, + pShareBuffer->Size, + pShareBuffer->Path, + pShareBuffer->SubDir, + pShareBuffer->Virtual, + pShareBuffer->DestShare + ); + + if (pShareBuffer->Root) + DumpDirBuffer(pShareBuffer->Root); + + if (pShareBuffer->Drive) + DumpDriveBuffer(pShareBuffer->Drive); + + if (pShareBuffer->DestShare) + if (!pShareBuffer->Virtual) + DumpShareBuffer(pShareBuffer->DestShare); + else + DumpVirtualShareBuffer((VIRTUAL_SHARE_BUFFER *)pShareBuffer->DestShare); + + dprintf( + TEXT("---SHARE_BUFFER(0x%08lx)\r\n"), + pShareBuffer + ); + } + else + dprintf(TEXT("Null pShareBuffer\r\n")); + +} // DumpShareBuffer + + +void DumpDriveList(DRIVE_LIST *pDriveList) +{ + ULONG index; + if (pDriveList) + { + dprintf(TEXT(">>>DRIVE_LIST(0x%08lx)(%d entries)\r\n"), pDriveList, pDriveList->Count); + for (index = 0; index < pDriveList->Count; index++ ) + DumpDriveBuffer(&pDriveList->DList[index]); + } + else + dprintf(TEXT("Null pDriveList\r\n")); + +} // DumpDriveList + + +void DumpDriveBuffer(DRIVE_BUFFER *pDriveBuffer) +{ + if (pDriveBuffer) + { + dprintf( + TEXT("+++DRIVE_BUFFER(0x%08lx)"), + pDriveBuffer + ); + + dprintf( + TEXT("\r\n\tType = 0x%08lx") + TEXT("\r\n\tDrive = %s") + TEXT("\r\n\tDriveType = %s") + TEXT("\r\n\tName = %s") + TEXT("\r\n\tTotalSpace = 0x%08lx") + TEXT("\r\n\tFreeSpace = 0x%08lx") + TEXT("\r\n\tAllocSpace = 0x%08lx\r\n"), + pDriveBuffer->Type, + pDriveBuffer->Drive, + pDriveBuffer->DriveType, + pDriveBuffer->Name, + pDriveBuffer->TotalSpace, + pDriveBuffer->FreeSpace, + pDriveBuffer->AllocSpace + ); + + dprintf( + TEXT("---DRIVE_BUFFER(0x%08lx)\r\n"), + pDriveBuffer + ); + } + else + dprintf(TEXT("Null pDriveBuffer)\r\n")); + +} // DumpDriveBuffer + + +void DumpDirBuffer(DIR_BUFFER *pDirBuffer) +{ + if (pDirBuffer) + { + dprintf( + TEXT("+++DIR_BUFFER(0x%08lx)"), + pDirBuffer + ); + + dprintf( + TEXT("\r\n\tName = %s") + TEXT("\r\n\tparent = 0x%08lx") + TEXT("\r\n\tLast = 0x%08lx") + TEXT("\r\n\tAttributes = 0x%08lx") + TEXT("\r\n\tConvert = 0x%08lx") + TEXT("\r\n\tSpecial = 0x%08lx") + TEXT("\r\n\tDirList = 0x%08lx") + TEXT("\r\n\tFileList = 0x%08lx\r\n"), + pDirBuffer->Name, + pDirBuffer->parent, + pDirBuffer->Last, + pDirBuffer->Attributes, + pDirBuffer->Convert, + pDirBuffer->Special, + pDirBuffer->DirList, + pDirBuffer->FileList + ); + +// if (pDirBuffer->DirList) +// DumpDirList(pDirBuffer->DirList); + +// if (pDirBuffer->FileList) +// DumpFileList(pDirBuffer->FileList); + + dprintf( + TEXT("---DIR_BUFFER(0x%08lx)\r\n"), + pDirBuffer + ); + } + else + dprintf(TEXT("Null pDirBuffer\r\n")); + +} // DumpDirBuffer +#endif diff --git a/private/nw/convert/nwconv/debug.h b/private/nw/convert/nwconv/debug.h new file mode 100644 index 000000000..19cfcdb95 --- /dev/null +++ b/private/nw/convert/nwconv/debug.h @@ -0,0 +1,34 @@ + +#ifndef _DEBUG_ +#define _DEBUG_ + +#ifdef __cplusplus +extern "C"{ +#endif + +void __cdecl dprintf(LPTSTR szFormat, ...); + +#ifdef DUMP + +#include "netutil.h" +#include "filesel.h" +#include "servlist.h" + +void DumpConvertList(CONVERT_LIST *pConvertList); +void DumpDestServerBuffer(DEST_SERVER_BUFFER *pDestServerBuffer); +void DumpSourceServerBuffer(SOURCE_SERVER_BUFFER *pSourceServerBuffer); +void DumpDomainBuffer(DOMAIN_BUFFER *pDomainBuffer); +void DumpVirtualShareBuffer(VIRTUAL_SHARE_BUFFER *pVirtualShareBuffer); +void DumpShareList(SHARE_LIST *pShareList); +void DumpShareBuffer(SHARE_BUFFER *pShareBuffer); +void DumpDriveList(DRIVE_LIST *pDriveList); +void DumpDriveBuffer(DRIVE_BUFFER *pDriveBuffer); +void DumpDirBuffer(DIR_BUFFER *pDirBuffer); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/encrypt.c b/private/nw/convert/nwconv/encrypt.c new file mode 100644 index 000000000..bfff89fe0 --- /dev/null +++ b/private/nw/convert/nwconv/encrypt.c @@ -0,0 +1,328 @@ + +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + encrypt.c + +Abstract: + + This module implements the routines for the NetWare + redirector to mangle an objectid, challenge key and + password such that a NetWare server will accept the + password as valid. + + This program uses information published in Byte Magazine. + +Author: + + Colin Watson [ColinW] 15-Mar-1993 + +Revision History: + +--*/ + + +#include +#include +#include +#include +// #include +#include +#include +// #include + +#define SWAPWORD(w) ((WORD)((w & 0xFF) << 8)|(WORD)(w >> 8)) +#define SWAPLONG(l) MAKELONG(SWAPWORD(HIWORD(l)),SWAPWORD(LOWORD(l))) + +#define NCP_WELL_KNOWN_SUPERVISOR_ID (ULONG) 0x00000001 +#define NCP_WELL_KNOWN_SUPERVISOR_ID_SWAPPED (ULONG) 0x01000000 +#define NCP_WELL_KNOWN_SUPERVISOR_ID_CHICAGO (ULONG) 0x00010000 +#define NCP_WELL_KNOWN_PSERVER_ID (ULONG) 0x00000002 + +#define NCP_PSERVER_SIGNATURE L"PS_" + +#define SWAP_OBJECT_ID(id) (id == NCP_WELL_KNOWN_SUPERVISOR_ID) ? \ + NCP_WELL_KNOWN_SUPERVISOR_ID_SWAPPED : \ + MAKELONG(LOWORD(id),SWAPWORD(HIWORD(id))) + + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Truncate all trailing zeros from the password. + // + + while (iPasswordLen > 0 && szUpperPassword[iPasswordLen-1] == 0 ) { + iPasswordLen--; + } + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + +NTSTATUS +ReturnNetwareForm( + const char * pszSecretValue, + DWORD dwUserId, + const WCHAR * pchNWPassword, + UCHAR * pchEncryptedNWPassword + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and encrypts it with the user + supplied password to develop a credential for the intermediate form. + +Arguments: + DWORD dwUserId - Supplies the 4 byte user's object id + const WCHAR * pchNWPassword - Supplies the user's password + + UCHAR * pchEncryptedNWPassword - 16 characters where the result goes. + +Return Value: + + none. + +--*/ + +{ + DWORD dwStatus; + DWORD chObjectId = SWAP_OBJECT_ID (dwUserId); + UNICODE_STRING uniNWPassword; + OEM_STRING oemNWPassword; + + // + // shuffle actually uses 32 bytes, not just 16. It only returns 16 though. + // + + UCHAR pszShuffledNWPassword[NT_OWF_PASSWORD_LENGTH * 2]; + + uniNWPassword.Buffer = (WCHAR *) pchNWPassword; + uniNWPassword.Length = lstrlenW (pchNWPassword)*sizeof(WCHAR); + uniNWPassword.MaximumLength = uniNWPassword.Length; + + if ((dwStatus = RtlUpcaseUnicodeStringToOemString (&oemNWPassword, + &uniNWPassword, + TRUE)) == STATUS_SUCCESS) + { + Shuffle((UCHAR *) &chObjectId, oemNWPassword.Buffer, oemNWPassword.Length, pszShuffledNWPassword); + + // Encrypt with LSA secret. + dwStatus = RtlEncryptNtOwfPwdWithUserKey( + (PNT_OWF_PASSWORD) pszShuffledNWPassword, + (PUSER_SESSION_KEY) pszSecretValue, + (PENCRYPTED_NT_OWF_PASSWORD) pchEncryptedNWPassword); + } + + return (dwStatus); +} diff --git a/private/nw/convert/nwconv/error.c b/private/nw/convert/nwconv/error.c new file mode 100644 index 000000000..d1bf87831 --- /dev/null +++ b/private/nw/convert/nwconv/error.c @@ -0,0 +1,69 @@ +/* + +-------------------------------------------------------------------------+ + | Error Handling Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [Error.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993] | + | Last Update : [Jun 18, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Jun 18, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "globals.h" + + +/*+-------------------------------------------------------------------------+ + | CriticalErrorExit() + | + | This should only be called when there is an unrecoverable error and + | the program must abort (such as running out of disk space on main + | system or out of memory). + | + | Can't dynamically load the error string (must do this at program + | init), because at time or error we might not be able to load it! + | + +-------------------------------------------------------------------------+*/ +void CriticalErrorExit(LPTSTR ErrorString) { + MessageBox(NULL, ErrorString, Lids(IDS_E_1), MB_ICONHAND | MB_SYSTEMMODAL | MB_OK); + exit(0); + +} // CriticalErrorExit + + + +/*+-------------------------------------------------------------------------+ + | WarningError() + | + | Pops up a warning message to the user - this should only be used + | when the user must be notified of something (the program stops until + | the user responds), but it is not so critical the the program has to + | abort. + | + | An example of this is if a config file is corrupt and the program + | will ignore it. + | + +-------------------------------------------------------------------------+*/ +void WarningError(LPTSTR ErrorString, ...) { + static TCHAR tmpStr[TMP_STR_LEN_256]; + va_list marker; + + va_start(marker, ErrorString); + wvsprintf(tmpStr, ErrorString, marker); + MessageBox(NULL, tmpStr, Lids(IDS_E_2), MB_ICONHAND | MB_OK); + va_end(marker); + +} // WarningError + + diff --git a/private/nw/convert/nwconv/error.h b/private/nw/convert/nwconv/error.h new file mode 100644 index 000000000..10d2451a4 --- /dev/null +++ b/private/nw/convert/nwconv/error.h @@ -0,0 +1,19 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HERROR_ +#define _HERROR_ + +#ifdef __cplusplus +extern "C"{ +#endif + +void CriticalErrorExit(LPTSTR ErrorString); +void WarningError(LPTSTR ErrorString, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/fastcopy.c b/private/nw/convert/nwconv/fastcopy.c new file mode 100644 index 000000000..e97191e10 --- /dev/null +++ b/private/nw/convert/nwconv/fastcopy.c @@ -0,0 +1,244 @@ +/* + +-------------------------------------------------------------------------+ + | File Copying Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FastCopy.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993] | + | Last Update : [Jun 18, 1994] | + | | + | Version: 1.00 | + | | + | Use multiple threads to whack data from one file to another | + | | + | Modifications: | + | 18-Oct-1990 w-barry Removed 'dead' code. | + | 21-Nov-1990 w-barry Updated API's to the Win32 set. | + | | + +-------------------------------------------------------------------------+ +*/ + +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES + +#include "globals.h" +#include +#include +#include +#include +#include "mem.h" +#include "debug.h" +#include "utils.h" +#include "convapi.h" + +#define BUFSIZE 0xFE00 // full segment minus sector +#define STACKSIZE 256 // stack size for child thread + +typedef struct BUF BUF; + +struct BUF { + BOOL flag; + DWORD cbBuf; + BUF *fpbufNext; + BYTE ach[BUFSIZE]; +}; + +#define LAST TRUE +#define NOTLAST FALSE + +static HANDLE hevQNotEmpty; +static CRITICAL_SECTION hcrtQLock; +static BUF *fpbufHead = NULL; +static BUF *fpbufTail = NULL; +static HANDLE hfSrc, hfDst; +static HANDLE hThread; +static BOOLEAN fAbort; + +// forward type definitions + +LPTSTR writer( void ); +DWORD reader( void ); +BUF *dequeue( void ); +void enqueue( BUF *fpbuf ); +TCHAR *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm ); + +/*+-------------------------------------------------------------------------+ + | writer() + | + +-------------------------------------------------------------------------+*/ +LPTSTR writer ( void ) { + BUF *fpbuf; + DWORD cbBytesOut; + BOOL f = !LAST; + LPTSTR npsz = NULL; + ULONG BytesCopied = 0; + + TCHAR buffer[MAX_PATH]; + + Status_Bytes(lToStr(BytesCopied)); + + while (f != LAST && npsz == NULL) { + fpbuf = dequeue (); + + if (fpbuf) { + if ((f = fpbuf->flag) != LAST) { + if (!WriteFile(hfDst, fpbuf->ach, fpbuf->cbBuf, &cbBytesOut, NULL)) { + npsz = Lids(IDS_L_4); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile\n")); +#endif + } else { + BytesCopied += cbBytesOut; + Status_Bytes(lToStr(BytesCopied)); + + + if (cbBytesOut != (DWORD)fpbuf->cbBuf) { + npsz = Lids(IDS_L_5); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile: out-of-space\n")); +#endif + } + } + } + else + npsz = *(LPTSTR *)fpbuf->ach; + + FreeMemory(fpbuf); + + } else { + wsprintf (buffer, Lids(IDS_L_4), fpbuf); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile - FileBuffer is NULL\n")); +#endif + } + } + + if (f != LAST) + fAbort = TRUE; + + WaitForSingleObject(hThread, (DWORD)-1); + CloseHandle(hThread); + CloseHandle(hevQNotEmpty); + DeleteCriticalSection(&hcrtQLock); + + return (npsz); +} // writer + + +/*+-------------------------------------------------------------------------+ + | reader() + | + +-------------------------------------------------------------------------+*/ +DWORD reader( void ) { + BUF *fpbuf; + BOOL f = !LAST; + + while (!fAbort && f != LAST) { + if ((fpbuf = AllocMemory(sizeof(BUF))) == NULL) { +#ifdef DEBUG +dprintf(TEXT("ERROR: MemoryAlloc error %ld\n"), GetLastError()); +#endif + return(0); + } + + f = fpbuf->flag = NOTLAST; + if (!ReadFile(hfSrc, fpbuf->ach, BUFSIZE, &fpbuf->cbBuf, NULL) || fpbuf->cbBuf == 0) { + f = fpbuf->flag = LAST; + *(LPTSTR *)(fpbuf->ach) = NULL; + } + + enqueue (fpbuf); + } + + return(0); +} // reader + + +/*+-------------------------------------------------------------------------+ + | dequeue() + | + +-------------------------------------------------------------------------+*/ +BUF *dequeue( void ) { + BUF *fpbuf; + + while (TRUE) { + if (fpbufHead != NULL) { + EnterCriticalSection(&hcrtQLock); + fpbufHead = (fpbuf = fpbufHead)->fpbufNext; + + if (fpbufTail == fpbuf) + fpbufTail = NULL; + + LeaveCriticalSection(&hcrtQLock); + break; + } + + // the head pointer is null so the list is empty. Block on eventsem + // until enqueue posts (ie. adds to queue) + WaitForSingleObject(hevQNotEmpty, (DWORD)-1); + } + + return fpbuf; +} // dequeue + + +/*+-------------------------------------------------------------------------+ + | enqueue() + | + +-------------------------------------------------------------------------+*/ +void enqueue( BUF *fpbuf ) { + fpbuf->fpbufNext = NULL; + + EnterCriticalSection(&hcrtQLock); + + if (fpbufTail == NULL) + fpbufHead = fpbuf; + else + fpbufTail->fpbufNext = fpbuf; + + fpbufTail = fpbuf; + LeaveCriticalSection(&hcrtQLock); + + SetEvent(hevQNotEmpty); +} // enqueue + + +/*+-------------------------------------------------------------------------+ + | fastcopy() + | + | hfSrcParm file handle to read from + | hfDstParm file handle to write to + | + | returns NULL if successful + | pointer to error string otherwise + +-------------------------------------------------------------------------+*/ +TCHAR *fastcopy (HANDLE hfSrcParm, HANDLE hfDstParm) { + DWORD dwReader; + + hfSrc = hfSrcParm; + hfDst = hfDstParm; + + + hevQNotEmpty = CreateEvent(NULL, (BOOL)FALSE, (BOOL)FALSE, NULL); + if (hevQNotEmpty == INVALID_HANDLE_VALUE) + return NULL; + + InitializeCriticalSection(&hcrtQLock); + + fAbort = FALSE; + hThread = CreateThread(0, STACKSIZE, (LPTHREAD_START_ROUTINE)reader, 0, 0, &dwReader); + if (hThread == INVALID_HANDLE_VALUE) { +#ifdef DEBUG +dprintf(TEXT("ERROR: Can't create thread - FileCopy\n")); +#endif + return Lids(IDS_L_6); + } + + return(writer()); +} // fastcopy + + diff --git a/private/nw/convert/nwconv/fcopy.c b/private/nw/convert/nwconv/fcopy.c new file mode 100644 index 000000000..6046ebad6 --- /dev/null +++ b/private/nw/convert/nwconv/fcopy.c @@ -0,0 +1,1162 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + FCopy.c + +Abstract: + + +Author: + + Arthur Hanson (arth) 16-Jun-1994 + +Revision History: + +--*/ + + +#include "globals.h" + +#include + +#include "nwconv.h" +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "userdlg.h" +#include "statbox.h" +#include "filedlg.h" + +// +// Defines used in CopyNode routine - used for figuring out if we are doing +// the home-directories in the MAIL sub-dir of the SYS vol. +// +#define DIR_TYPE_NORMAL 0 +#define DIR_TYPE_MAIL 1 +#define DIR_TYPE_LOGIN 2 + +static TCHAR SourcePath[MAX_UNC_PATH]; +static LPTSTR spPtr; +static FILE_OPTIONS *FileOptions = NULL; +static CONVERT_OPTIONS *CurrentConvertOptions = NULL; +static ULONG Count; +static ULONG ServShareLen = 0; + +static USER_LIST *Users; +static ULONG UserCount; +static GROUP_LIST *Groups; +static ULONG GroupCount; +static BOOL IsNTFSDrive; + +static PSECURITY_DESCRIPTOR pSD = NULL; +static PACL pACLNew = NULL; +static PSID pSID = NULL; +static ULONG CurSizeTotal; +static ULONG CurNumFiles; +static ULONG TotalSizeTotal; +static BOOL SysRoot = FALSE; +static BOOL SysVol = FALSE; + +extern UINT TotFiles; +extern TCHAR UserServerName[]; + +#define NWRIGHTSALL 0xFF + +#define BASE_16 16 + +#define SWAPWORD(w) ((WORD)((w & 0xFF) << 8)|(WORD)(w >> 8)) +#define SWAPLONG(l) MAKELONG(SWAPWORD(HIWORD(l)),SWAPWORD(LOWORD(l))) + + +TCHAR *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm ); + +USER_BUFFER *FindUserMatch(LPTSTR Name, USER_LIST *UserList, BOOL NewName); +GROUP_BUFFER *FindGroupMatch(LPTSTR Name, GROUP_LIST *GroupList, BOOL NewName); +BOOL NTFile_AccessRightsAdd(LPTSTR ServerName, LPTSTR pUserName, LPTSTR pFileName, ULONG Rights, BOOL Dir); +VOID ErrorIt(LPTSTR szFormat, ...); + +TCHAR SrcPath[MAX_UNC_PATH]; // +3 for slashes +TCHAR DestPath[MAX_UNC_PATH]; // +3 for slashes + + +///////////////////////////////////////////////////////////////////////// +VOID +ConvertFilesInit( + HWND hDlg + ) + +/*++ + +Routine Description: + + Initialization routine called before doing the file copying. Sets up + the information panel dialog and fills in the directory tree structures. + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_UNC_PATH]; + SOURCE_SERVER_BUFFER *SServ; + DEST_SERVER_BUFFER *DServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + SHARE_BUFFER *CurrentShare; + DRIVE_BUFFER *Drive; + VIRTUAL_SHARE_BUFFER *VShare; + ULONG i; + + // Just to be safe init this. + FillDirInit(); + TotFiles = 0; + TotalSizeTotal = 0; + + // Clear out old alloc space calculations + DServListSpaceFree(); + + CurrentConvertList = ConvertListStart; + while (CurrentConvertList) { + SServ = CurrentConvertList->SourceServ; + DServ = CurrentConvertList->FileServ; + ShareList = SServ->ShareList; + + FileOptions = (FILE_OPTIONS *) CurrentConvertList->FileOptions; + if (FileOptions->TransferFileInfo) { + if (ShareList) { + SList = ShareList->SList; + // First expand all the file trees + for (i = 0; i < ShareList->Count; i++) { + CurrentShare = &SList[i]; + if (CurrentShare->Convert) { + Panel_Line(1, Lids(IDS_D_1)); + Panel_Line(6, TEXT("%s\\%s:"), SServ->Name, CurrentShare->Name); + Panel_Line(2, Lids(IDS_D_2)); + Panel_Line(3, Lids(IDS_D_3)); + Panel_Line(4, Lids(IDS_D_4)); + wsprintf(NewPath, TEXT("\\\\%s\\%s\\"), SServ->Name, CurrentShare->Name); + + if (CurrentShare->Root == NULL) + TreeRootInit(CurrentShare, NewPath); + + TreeFillRecurse(1, NewPath, CurrentShare->Root); + + // Now increment allocated space on dest drive + if (CurrentShare->DestShare != NULL) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + Drive = VShare->Drive; + + if (Drive != NULL) + Drive->AllocSpace += TotalFileSizeGet(); + + } else { + Drive = CurrentShare->DestShare->Drive; + if (Drive != NULL) + Drive->AllocSpace += TotalFileSizeGet(); + } + + } + } // expand the file trees... + } + + } // if transfer files + + CurrentConvertList = CurrentConvertList->next; + } // loop through servers + +} // ConvertFilesInit + + +///////////////////////////////////////////////////////////////////////// +PSECURITY_DESCRIPTOR +SecurityDescriptorCreate( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + Creates a security descriptor. + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD cbACL = 1024; + DWORD cbSID = 1024; + LPTSTR lpszAccount; + TCHAR lpszDomain[80]; + DWORD cchDomainName = 80; + UCHAR psnuType[1024]; + ACCESS_ALLOWED_ACE *pAAAce; + + lpszAccount = Lids(IDS_S_1); + + // Initialize a new security descriptor. + pSD = (PSECURITY_DESCRIPTOR) AllocMemory(SECURITY_DESCRIPTOR_MIN_LENGTH); + if (pSD == NULL) + return NULL; + + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { + FreeMemory(pSD); + return NULL; + } + + // Initialize a new ACL. + pACLNew = (PACL) AllocMemory(cbACL); + if (pACLNew == NULL) { + goto Cleanup; + } + + if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION2)) { + goto Cleanup; + } + + // Retrieve the SID for UserABC. + pSID = (PSID) AllocMemory(cbSID); + if (pSID == NULL) { + goto Cleanup; + } + + if (!LookupAccountName(ServerName, lpszAccount, pSID, &cbSID, + lpszDomain, &cchDomainName, (PSID_NAME_USE) psnuType)) { + goto Cleanup; + } + + // Set access permissions + if (!AddAccessAllowedAce(pACLNew, ACL_REVISION2, GENERIC_ALL, pSID)) { + goto Cleanup; + } + + if (!GetAce(pACLNew, 0, (LPVOID *) &pAAAce)) + goto Cleanup; + + pAAAce->Header.AceFlags |= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE; + pAAAce->Mask = GENERIC_ALL; + + // Add a new ACL to the security descriptor. + if (!SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE)) { + goto Cleanup; + } + + return pSD; + +Cleanup: + + if (pSID != NULL) + FreeSid(pSID); + + if(pSD != NULL) + FreeMemory(pSD); + + if(pACLNew != NULL) + FreeMemory(pACLNew); + + return NULL; + +} // SecurityDescriptorCreate + + +///////////////////////////////////////////////////////////////////////// +VOID +MakeDir ( + DEST_SERVER_BUFFER *DServ, + VIRTUAL_SHARE_BUFFER *VShare + ) + +/*++ + +Routine Description: + + Given a path, this will start at the root of the path and create a + directory tree up to the ending node. + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_UNC_PATH]; + TCHAR oc; + LPTSTR ptr; + TCHAR ServerName[MAX_SERVER_NAME_LEN + 3]; + SECURITY_ATTRIBUTES sa; + + // First need to construct a root path in the correct form + wsprintf(NewPath, TEXT("\\\\%s\\%s"), DServ->Name, VShare->Path); + + ptr = NewPath; + if (*ptr == TEXT('\0')) + return; + + // Look for ":" and change to the "$" + while (*ptr && *ptr != TEXT(':')) + ptr++; + + if (*ptr == TEXT(':')) + *ptr = TEXT('$'); + else + return; + + // Go to initial backslash (one right after drive designator) + while (*ptr && *ptr != TEXT('\\')) + ptr++; + + // We are pointing at the first char of the path - now loop through + // the path - looking for each backslash and make each sub-dir + // individually. + while (*ptr) { + // skip over backslash we are on + ptr++; + + while (*ptr && *ptr != TEXT('\\')) + ptr++; + + // sitting on next backslash - truncate path and make the dir + oc = *ptr; + *ptr = TEXT('\0'); + + wsprintf(ServerName, TEXT("\\\\%s"), DServ->Name); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = SecurityDescriptorCreate(ServerName); + sa.bInheritHandle = TRUE; + + CreateDirectory(NewPath, &sa); + + // Now cleanup the allocated security stuff + if (pSID != NULL) + FreeSid(pSID); + + if(pSD != NULL) + FreeMemory(pSD); + + if(pACLNew != NULL) + FreeMemory(pACLNew); + + *ptr = oc; + } + +} // MakeDir + + +///////////////////////////////////////////////////////////////////////// +VOID +VSharesCreate( + DEST_SERVER_BUFFER *DServ, + BOOL TConversion + ) + +/*++ + +Routine Description: + + Given a virtual share struct, creates the share on the destination + server, include both an NT share and FPNW share if applicable. Will + also create any directories to point the share at if needed. + +Arguments: + + +Return Value: + + +--*/ + +{ + CONVERT_OPTIONS *cvo; + VIRTUAL_SHARE_BUFFER *VShare; + BOOL FPNWChk; + + LogWriteLog(0, Lids(IDS_L_7)); + VShare = CurrentConvertList->FileServ->VShareStart; + cvo = (CONVERT_OPTIONS *) CurrentConvertList->ConvertOptions; + + FPNWChk = DServ->IsFPNW; + + while (VShare) { + if (VShare->UseCount > 0) { + LogWriteLog(1, TEXT("%s \r\n"), VShare->Name); + LogWriteLog(2, Lids(IDS_L_8), VShare->Path); + + if (!TConversion) { + MakeDir(DServ, VShare); + if ((cvo->NetWareInfo) && FPNWChk) + FPNWShareAdd(VShare->Name, VShare->Path); + + NTShareAdd(VShare->Name, VShare->Path); + } + + } + + VShare = VShare->next; + } + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // VSharesCreate + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSecurityTransfer( + LPTSTR SrcPath, + LPTSTR DestPath, + BOOL TConversion, + BOOL Dir + ) + +/*++ + +Routine Description: + + Given a source and destination path, will take all the file permissions + from the source and apply them to the destination. Will automatically + convert any user names to their new equivalence. + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL match; + LPTSTR fnPtr; + USER_RIGHTS_LIST *secUsers = NULL; + ULONG secUserCount; + ULONG i; + USER_BUFFER *FoundUser; + GROUP_BUFFER *FoundGroup; + LPTSTR NewName; + ACCESS_MASK AccessMask; + NTSTATUS ntstatus; + BOOL DidEveryone = FALSE; + + fnPtr = &SrcPath[ServShareLen]; + + lstrcat(SourcePath, fnPtr); + ErrorItemSet(Lids(IDS_L_9), SourcePath); + +#ifdef DEBUG +dprintf(TEXT("Getting Rights for: %s\n"), SourcePath); +#endif + if (!NWFileRightsEnum(SourcePath, &secUsers, &secUserCount, (CurrentConvertList->SourceServ->VerMaj < 3))) { + + if (VerboseFileLogging() && (secUserCount > 0)) + if (Dir) + LogWriteLog(2, Lids(IDS_L_10)); + else + LogWriteLog(3, Lids(IDS_L_10)); + + for (i = 0; i < secUserCount; i++) { +#ifdef DEBUG + dprintf(TEXT("%s %s\n"), NWRightsLog(secUsers[i].Rights), secUsers[i].Name); +#endif + + match = FALSE; + FoundUser = FindUserMatch(secUsers[i].Name, Users, FALSE); + + // Check if this is "EVERYONE" + if (!lstrcmpi(secUsers[i].Name, Lids(IDS_S_31))) + DidEveryone = TRUE; + + if (FoundUser == NULL) { + FoundGroup = FindGroupMatch(secUsers[i].Name, Groups, FALSE); + if (FoundGroup != NULL) { + match = TRUE; + NewName = FoundGroup->NewName; + + } + } else { + match = TRUE; + NewName = FoundUser->NewName; + } + + if (!match) + NewName = NWSpecialNamesMap(secUsers[i].Name); + + // Map the NW rights to NT access mask + AccessMask = 0x0; + + if (Dir) + ntstatus = MapNwRightsToNTAccess(secUsers[i].Rights, &DirRightsMapping, &AccessMask); + else + ntstatus = MapNwRightsToNTAccess(secUsers[i].Rights, &FileRightsMapping, &AccessMask); + + if (VerboseFileLogging()) + if (Dir) + LogWriteLog(3, TEXT("%s %-20s -> %-20s %s\r\n"), NWRightsLog(secUsers[i].Rights), secUsers[i].Name, NewName, NTAccessLog(AccessMask)); + else + LogWriteLog(4, TEXT("%s %-20s -> %-20s %s\r\n"), NWRightsLog(secUsers[i].Rights), secUsers[i].Name, NewName, NTAccessLog(AccessMask)); + + if (NT_SUCCESS(ntstatus)) { +#ifdef DEBUG +dprintf(TEXT("Server: %s\n"), UserServerName); +#endif + if (!TConversion) + NTFile_AccessRightsAdd(UserServerName, NewName, DestPath, AccessMask, Dir); + } +#ifdef DEBUG + else + dprintf(TEXT("NwAddRight: MapNwRightsToNTAccess failed\n")); +#endif + } + + FreeMemory(secUsers); + } + + // + // If this is the root of the sys vol, and the rights for Everyone weren't + // transferred, then Give everyone access. NT and NetWare handle + // permissions a bit differently. In NW if a user has permission + // nested down in a sub-dir, then NW will back-port S permission down + // to the root so the user can get access into the sub-dir. NT does + // access from the root up. Giving the user RX access provides a + // workaround. + // + if (SysRoot && !DidEveryone) { + // Use "Domain Users" for the user - equiv of everyone. + NewName = Lids(IDS_S_33); + // Map the NW rights to NT access mask + AccessMask = 0x0; + + ntstatus = MapNwRightsToNTAccess(NW_FILE_READ, &DirRightsMapping, &AccessMask); + + if (VerboseFileLogging()) + LogWriteLog(3, TEXT("%s %-20s -> %-20s %s\r\n"), NWRightsLog(NW_FILE_READ), Lids(IDS_S_31), NewName, NTAccessLog(AccessMask)); + + if (NT_SUCCESS(ntstatus) && !TConversion) + NTFile_AccessRightsAdd(UserServerName, NewName, DestPath, AccessMask, Dir); + } + + // re-truncate share name + *spPtr = TEXT('\0'); + +} // FileSecurityTransfer + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +fcopy ( + LPTSTR src, + LPTSTR dst + ) + +/*++ + +Routine Description: + + fcopy (source file, destination file) copies the source to the destination + preserving attributes and filetimes. Returns NULL if OK or a char pointer + to the corresponding text of the error + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR fcopyErrorText[128]; + HANDLE srcfh = INVALID_HANDLE_VALUE; + HANDLE dstfh = INVALID_HANDLE_VALUE; + LPTSTR result = NULL; + DWORD attribs; + FILETIME CreationTime, LastAccessTime, LastWriteTime; + + attribs = GetFileAttributes(src); + if (attribs == FILE_ATTRIBUTE_DIRECTORY) { + result = Lids(IDS_L_11); + goto done; + } + + if( ( srcfh = CreateFile( src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ) ) == (HANDLE)-1 ) { + wsprintf( fcopyErrorText, Lids(IDS_L_12), GetLastError() ); + result = fcopyErrorText; + goto done; + } + + if (!GetFileTime(srcfh, &CreationTime, &LastAccessTime, &LastWriteTime)) { + result = Lids(IDS_L_13); + goto done; + } + + if( ( dstfh = CreateFile( dst, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, srcfh ) ) == INVALID_HANDLE_VALUE) { + wsprintf( fcopyErrorText, Lids(IDS_L_14), GetLastError() ); + result = fcopyErrorText; + goto done; + } + + result = fastcopy( srcfh, dstfh ); + + if( result != NULL ) { + if (dstfh != INVALID_HANDLE_VALUE) { + CloseHandle( dstfh ); + dstfh = INVALID_HANDLE_VALUE; + } + + DeleteFile( dst ); + goto done; + } + + if (!SetFileTime(dstfh, &CreationTime, &LastAccessTime, &LastWriteTime)) { + result = Lids(IDS_L_15); + goto done; + } + + if (attribs != 0xFFFFFFFF) + if (!SetFileAttributes(dst, attribs)) { + result = Lids(IDS_L_16); + goto done; + } + +done: + if (srcfh != INVALID_HANDLE_VALUE) + CloseHandle( srcfh ); + + if (dstfh != INVALID_HANDLE_VALUE) + CloseHandle( dstfh ); + + return result; +} // fcopy + + +///////////////////////////////////////////////////////////////////////// +BOOL +LoginDirConvert( + LPTSTR OldName, + LPTSTR NewName + ) + +/*++ + +Routine Description: + + We need to copy login scripts, these reside in the mail directory on + the NetWare server. Each user's OBJECT_ID is a sub-directory. What + needs to be done is scan the sub-directories and convert the + OBJECT_ID for each user to the corresponding new OBJECT_ID on the + NT Server and rename the sub-dir to this new OBJECT_ID value. Then + copy the files. + + The copy of the files and saving of the directory is done in + CopyNode, this routine converts the OBJECT-ID's. + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD OldID, NewID; + USER_BUFFER *FoundUser; + char aOldName[MAX_PATH + 1]; + TCHAR OldUserName[MAX_PATH + 1]; + LPTSTR NewUserName; + BOOL ret = TRUE; + + // + // Need to take several conversion steps. We are passed in a string + // representation of the OBJECT-ID. This needs to be changed into + // the new string represenation of the new OBJECT-ID as follows: + // + // 1. Str-OBJECTID -> OBJECT-ID (DWORD) + // 2. OBJECT-ID -> Name (User Name on NW server) + // 3. Name -> New Name (on NT Server) + // 4. New Name -> OBJECT-ID (DWORD) + // 5. OBJECT-ID -> Str-OBJECTID + // + + // + // Init just in case + // + lstrcpy(NewName, TEXT("")); + strcpy(aOldName, ""); + OldID = NewID = 0; + + // + // 1. Str-OBJECTID -> OBJECT-ID (DWORD) + // + WideCharToMultiByte(CP_ACP, 0, OldName, -1, aOldName, sizeof(aOldName), NULL, NULL); + RtlCharToInteger(aOldName, BASE_16, &OldID); + SWAPWORDS(OldID); + + // + // If we didn't convert it, or not an Object ID, then use original string + // + if (OldID == 0) { + lstrcpy(NewName, OldName); + ret = FALSE; + goto LoginDirConvertExit; + } + + // + // 2. OBJECT-ID -> Name (User Name on NW server) + // + if (!NWObjectNameGet(OldID, OldUserName)) { + lstrcpy(NewName, OldName); + ret = FALSE; + goto LoginDirConvertExit; + } + + // + // 3. Name -> New Name (on NT Server) + // + FoundUser = FindUserMatch(OldUserName, Users, FALSE); + NewUserName = OldUserName; + + if (FoundUser != NULL) + NewUserName = FoundUser->NewName; + + // + // 4. New Name -> OBJECT-ID (DWORD) + // + NewID = NTObjectIDGet(NewUserName); + + if (NewID == 0) { + lstrcpy(NewName, OldName); + ret = FALSE; + goto LoginDirConvertExit; + } + + // + // 5. OBJECT-ID -> Str-OBJECTID + // + wsprintf(NewName, TEXT("%lX"), MAKELONG(HIWORD(NewID),SWAPWORD(LOWORD(NewID))) ); + +LoginDirConvertExit: +#ifdef DEBUG + if (ret) + dprintf(TEXT("Converting Login Dir for [%s]: %s -> %s\n"), OldUserName, OldName, NewName); +#endif + + return ret; + +} // LoginDirConvert + + +///////////////////////////////////////////////////////////////////////// +VOID +CopyNode( + DIR_BUFFER *Dir, + BOOL First, + BOOL TConversion, + DWORD DirType + ) + +/*++ + +Routine Description: + + A node in this case is a sub-directory. This is a recursive function that + will copy all files and sub-directories under a given sub-directory. + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR ErrText; + DIR_LIST *DirList = NULL; + FILE_LIST *FileList = NULL; + DIR_BUFFER *DList; + FILE_BUFFER *FList; + LPTSTR pSrcPath, pDestPath; + TCHAR Attributes[10]; + ULONG i; + DWORD ChildDirType; + DWORD attribs; + + if (Dir == NULL) + return; + + if (!Dir->Convert) + return; + + SysRoot = FALSE; + + // 1. Make dir if need be. + // 2. Copy all files in this dir + // 3. For each sub-dir recurse into this function, building up the path + + // + // 1. Make Dir + // + if (!First) { + lstrcat(SrcPath, Dir->Name); + + // + // If a HOME directory, then we need to convert the name to the new + // USER-ID + // + if (DirType == DIR_TYPE_LOGIN) { + TCHAR NewDirName[MAX_PATH + 1]; + + if (!LoginDirConvert(Dir->Name, NewDirName)) + return; + + lstrcat(DestPath, NewDirName); + } else + lstrcat(DestPath, Dir->Name); + + if (!TConversion) { + attribs = GetFileAttributes(SrcPath); + CreateDirectory(DestPath, NULL); + + if (attribs != 0xFFFFFFFF) + SetFileAttributes(DestPath, attribs); + } + + } else { + lstrcat(DestPath, TEXT("\\")); + + // Check if this is the root of the sys dir (for special security transfer). + if (SysVol) + SysRoot = TRUE; + } + + if (VerboseFileLogging()) { + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(2, Lids(IDS_L_17), SrcPath); + LogWriteLog(2, Lids(IDS_L_18), DestPath); + } + + if (IsNTFSDrive) + FileSecurityTransfer(SrcPath, DestPath, TConversion, TRUE); + + // No need for this anymore + SysRoot = FALSE; + + // Fixup and remember our path + lstrcat(SrcPath, TEXT("\\")); + + if (!First) + lstrcat(DestPath, TEXT("\\")); + + Status_ItemLabel(Lids(IDS_L_19), NicePath(50, SrcPath)); + + // Remember where end of source and dest paths are - so we don't have to + // store them on the stack all the time + pSrcPath = SrcPath; + while (*pSrcPath) + pSrcPath++; + + pDestPath = DestPath; + while (*pDestPath) + pDestPath++; + + Status_CurNum((UINT) Count+1); + + // + // 2. Copy All Files in this dir + // + FileList = Dir->FileList; + if (FileList) { + + if (FileList->Count > 0) + LogWriteLog(2, Lids(IDS_L_20)); + + FList = FileList->FileBuffer; + for (i = 0; i < FileList->Count; i++) + if (FList[i].Convert) { + ErrText = NULL; + lstrcat(SrcPath, FList[i].Name); + lstrcat(DestPath, FList[i].Name); + Status_CurNum((UINT) Count+1); +#ifdef DEBUG +dprintf(TEXT("FC: %s -> %s\n"), SrcPath, DestPath); +#endif + ErrorItemSet(Lids(IDS_L_19), SrcPath); + Status_Item(FList[i].Name); + TotFiles++; + CurNumFiles++; + Status_TotFiles(TotFiles); + Count++; + + Status_TotBytes(lToStr(FList[i].Size)); + + if (!TConversion) { + ErrText = fcopy(SrcPath, DestPath); + + if (IsNTFSDrive) + FileSecurityTransfer(SrcPath, DestPath, TConversion, FALSE); + } + + if (VerboseFileLogging()) { + lstrcpy(Attributes, Lids(IDS_L_21)); + if (!(FList[i].Attributes & FILE_ATTRIBUTE_READONLY)) + Attributes[1] = TEXT(' '); + + if (!(FList[i].Attributes & FILE_ATTRIBUTE_ARCHIVE)) + Attributes[2] = TEXT(' '); + + if (!(FList[i].Attributes & FILE_ATTRIBUTE_HIDDEN)) + Attributes[3] = TEXT(' '); + + if (!(FList[i].Attributes & FILE_ATTRIBUTE_SYSTEM)) + Attributes[4] = TEXT(' '); + + LogWriteLog(3, TEXT("%13s %s %s\r\n"), lToStr(FList[i].Size), Attributes, FList[i].Name); + } + + if (ErrText != NULL) { + if (!VerboseFileLogging()) + LogWriteLog(3, Lids(IDS_L_22), SrcPath, DestPath); + + LogWriteLog(4, TEXT("%s\r\n"), ErrText); + ErrorIt(TEXT("%s\r\n"), ErrText); + } else { + CurSizeTotal += FList[i].Size; + TotalSizeTotal += FList[i].Size; + } + + // reset our paths to the right place + *pSrcPath = TEXT('\0'); + *pDestPath = TEXT('\0'); + } + + } + + // + // 3. Recurse the sub-dirs + // + DirList = Dir->DirList; + if (DirList) { + DList = DirList->DirBuffer; + for (i = 0; i < DirList->Count; i++) + if (DList[i].Convert) { + + // + // Reset child dir type... + // + ChildDirType = DIR_TYPE_NORMAL; + + // + // If this is the mail sub-dir, then the children are home-dirs + // + if (DirType == DIR_TYPE_MAIL) + ChildDirType = DIR_TYPE_LOGIN; + + // recurse into this dir - check if this is the mail dir + if (SysVol && First && !lstrcmpi(DList[i].Name, TEXT("MAIL")) && CurrentConvertList->FileServ->IsFPNW ) + ChildDirType = DIR_TYPE_MAIL; + + CopyNode(&DList[i], FALSE, TConversion, ChildDirType); + + // reset our paths to the right place + *pSrcPath = TEXT('\0'); + *pDestPath = TEXT('\0'); + } + } // Recursing Sub-dirs + +} // CopyNode + + +///////////////////////////////////////////////////////////////////////// +VOID +ConvertFiles( + HWND hDlg, + BOOL TConversion, + USER_LIST *iUsers, + GROUP_LIST *iGroups + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_LIST *DirList = NULL; + SOURCE_SERVER_BUFFER *SServ; + DEST_SERVER_BUFFER *DServ; + VIRTUAL_SHARE_BUFFER *VShare; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + SHARE_BUFFER *CurrentShare; + ULONG i; + + Users = iUsers; + Groups = iGroups; + + if (iUsers != NULL) + UserCount = iUsers->Count; + else + UserCount = 0; + + if (iGroups != NULL) + GroupCount = iGroups->Count; + else + GroupCount = 0; + + Count = 0; + FileOptions = (FILE_OPTIONS *) CurrentConvertList->FileOptions; + CurrentConvertOptions = (CONVERT_OPTIONS *) CurrentConvertList->ConvertOptions; + SServ = CurrentConvertList->SourceServ; + DServ = CurrentConvertList->FileServ; + + // Synchronize the domain + NTDomainSynch(DServ); + + // Following steps are taken: + // 1. Enumerate / create all virtual shares + // 2. Enumerate volumes and destinations to convert + // 3. Go to each volume - copy that tree + + ShareList = SServ->ShareList; + + if (VerboseFileLogging()) { + LogWriteLog(0, Lids(IDS_LINE)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_23)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_24)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_25)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_26)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_27)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_28)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_29)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_30)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_31)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_32)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_33)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_34)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_35)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_36)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_37)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_38)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_39)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_40)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_41)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_42)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_43)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_44)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_45)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_46)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_47)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_48)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_49)); + LogWriteLog(0, Lids(IDS_LINE)); + } + + LogWriteLog(0, Lids(IDS_L_20)); + Status_ConvTxt(Lids(IDS_L_50)); + Status_ItemLabel(Lids(IDS_L_51)); + + if (ShareList) { + SList = ShareList->SList; + + for (i = 0; i < ShareList->Count; i++) { + Count = 0; + CurrentShare = &SList[i]; + if (CurrentShare->Root) + Status_CurTot((UINT) TreeCount(CurrentShare->Root)); + + if (CurrentShare->Convert) { + // Set root paths for this conversion + memset(SrcPath, 0, sizeof(SrcPath)); + wsprintf(SrcPath, TEXT("\\\\%s\\%s"), SServ->Name, CurrentShare->Name); + ServShareLen = lstrlen(SrcPath) + 1; + + // create sharename for access rights query in form of "SHARE:" + memset(SourcePath, 0, sizeof(SourcePath)); + lstrcpy(SourcePath, CurrentShare->Name); + lstrcat(SourcePath, TEXT(":")); + + // Check if this is the root of the sys dir (for special security transfer). + SysVol = FALSE; + if (!lstrcmpi(CurrentShare->Name, Lids(IDS_S_6))) + SysVol = TRUE; + + // point spPtr to ending NULL so we can truncate it back + spPtr = &SourcePath[lstrlen(SourcePath)]; + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(1, Lids(IDS_L_52), CurrentShare->Name); + LogWriteSummary(1, Lids(IDS_L_52), CurrentShare->Name); + + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + // + // NOTE: The DestShare->Name may be that of the ncp server so + // instead of formatting the destination \\server\share\, + // which means nothing to the smb server if the share is fpnw, + // we format the destination \\server\d$\path\. + // + wsprintf(DestPath, TEXT("\\\\%s\\%s"), DServ->Name, VShare->Path); + DestPath[2+lstrlen(DServ->Name)+1+1] = TEXT('$'); // replace ':' with '$' in unc path + + if (VShare->Drive != NULL) + IsNTFSDrive = (VShare->Drive->Type == DRIVE_TYPE_NTFS); + else + IsNTFSDrive = FALSE; + + LogWriteLog(1, Lids(IDS_L_53), VShare->Name); + LogWriteSummary(1, Lids(IDS_L_53), VShare->Name); + } else { + // + // NOTE: The DestShare->Name may be that of the ncp server so + // instead of formatting the destination \\server\share\, + // which means nothing to the smb server if the share is fpnw, + // we format the destination \\server\d$\path\. + // + wsprintf(DestPath, TEXT("\\\\%s\\%s"), DServ->Name, CurrentShare->DestShare->Path); + DestPath[2+lstrlen(DServ->Name)+1+1] = TEXT('$'); // replace ':' with '$' in unc path + + if (CurrentShare->DestShare->Drive != NULL) + IsNTFSDrive = (CurrentShare->DestShare->Drive->Type == DRIVE_TYPE_NTFS); + else + IsNTFSDrive = FALSE; + + LogWriteLog(1, Lids(IDS_L_53), CurrentShare->DestShare->Name); + LogWriteSummary(1, Lids(IDS_L_53), CurrentShare->DestShare->Name); + } + + CurSizeTotal = 0; + CurNumFiles = 0; + CopyNode(CurrentShare->Root, TRUE, TConversion, (DWORD) DIR_TYPE_NORMAL); + LogWriteSummary(2, Lids(IDS_L_54), lToStr(CurNumFiles)); + LogWriteSummary(2, Lids(IDS_L_55), lToStr(CurSizeTotal)); + + // Whack it down to minimum size to conserve memory + TreePrune(CurrentShare->Root); + } + } + } + +} // ConvertFiles diff --git a/private/nw/convert/nwconv/filedlg.c b/private/nw/convert/nwconv/filedlg.c new file mode 100644 index 000000000..567106a6b --- /dev/null +++ b/private/nw/convert/nwconv/filedlg.c @@ -0,0 +1,1074 @@ +/* + +-------------------------------------------------------------------------+ + | File Operations | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FileDLG.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 10, 1994] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Feb 10, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" + +#include "convapi.h" +#include "filedlg.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "columnlb.h" + +static SOURCE_SERVER_BUFFER *SServ; +static DEST_SERVER_BUFFER *DServ; + +static FILE_OPTIONS *FileOptions; +static SHARE_LIST *ShareList; +static SHARE_BUFFER *SList; +static SHARE_BUFFER *CurrentShare; +static SHARE_BUFFER *CurrentDShare; +static int SelectType; +static int NewShareType; + +#define SELECT_TYPE_MODIFY 1 +#define SELECT_TYPE_ADD 2 + +static BOOL ConvertFiles = TRUE; + +void FileSelect_Do(HWND hDlg, SOURCE_SERVER_BUFFER *SourceServ, SHARE_BUFFER *CShare); +BOOL MapShare(SHARE_BUFFER *Share, DEST_SERVER_BUFFER *DServ); + + +/*+-------------------------------------------------------------------------+ + | FileOptionsDefaultsSet() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsDefaultsSet(void *tfo) { + FILE_OPTIONS *fo = tfo; + + if (fo->TransferFileInfo) + ConvertFiles = TRUE; + else + ConvertFiles = FALSE; + +} // FileOptionsDefaultsSet + + +/*+-------------------------------------------------------------------------+ + | FileOptionsDefaultsReset() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsDefaultsReset() { + ConvertFiles = TRUE; + +} // FileOptionsDefaultsReset + + +/*+-------------------------------------------------------------------------+ + | FileOptionsInit() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsInit(void **lpfo) { + FILE_OPTIONS *fo; + + fo = (FILE_OPTIONS *) *lpfo; + + // if we need to allocate space, do so + if (fo == NULL) + fo = AllocMemory(sizeof(FILE_OPTIONS)); + + // make sure it was allocated + if (fo == NULL) + return; + + memset(fo, 0, sizeof(FILE_OPTIONS)); + fo->TransferFileInfo = ConvertFiles; + *lpfo = (void *) fo; + +} // FileOptionsInit + + +/*+-------------------------------------------------------------------------+ + | FileOptionsLoad() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsLoad(HANDLE hFile, void **lpfo) { + FILE_OPTIONS *fo; + DWORD wrote; + + fo = (FILE_OPTIONS *) *lpfo; + + // if we need to allocate space, do so + if (fo == NULL) + fo = AllocMemory(sizeof(FILE_OPTIONS)); + + // make sure it was allocated + if (fo == NULL) + return; + + ReadFile(hFile, fo, sizeof(FILE_OPTIONS), &wrote, NULL); + *lpfo = (void *) fo; + +} // FileOptionsLoad + + +/*+-------------------------------------------------------------------------+ + | FileOptionsSave() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsSave(HANDLE hFile, void *fo) { + DWORD wrote; + + WriteFile(hFile, fo, sizeof(FILE_OPTIONS), &wrote, NULL); + +} // FileOptionsSave + + +/*+-------------------------------------------------------------------------+ + | Share Modify/Create Dialog Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ShareNewPathValidate() + | + +-------------------------------------------------------------------------+*/ +BOOL ShareNewPathValidate(HWND hWnd, LPTSTR Path, DRIVE_BUFFER **pDrive) { + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *DList; + ULONG i; + TCHAR Drive[2]; + + // must be long enough to hold drive, colon and path + if (lstrlen(Path) < 3) + goto ShareNewValidateFail; + + if (Path[1] != TEXT(':')) + goto ShareNewValidateFail; + + if (Path[2] != TEXT('\\')) + goto ShareNewValidateFail; + + if (DServ->DriveList == NULL) + return FALSE; + + // Scan drive list looking for match to share path + Drive[1] = TEXT('\0'); + DList = DServ->DriveList->DList; + for (i = 0; i < DServ->DriveList->Count; i++) { + // Get first char from path - should be drive letter + Drive[0] = Path[0]; + if (!lstrcmpi(Drive, DList[i].Drive)) { + // Found match + *pDrive = &DList[i]; + + if (NewShareType == SELECT_TYPE_MODIFY) + if (CurrentDShare->VFlag) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentDShare; + VShare->Drive = &DList[i]; + } else + CurrentDShare->Drive = &DList[i]; + + return TRUE; + } + } + +ShareNewValidateFail: + MessageBox(hWnd, Lids(IDS_E_3), Lids(IDS_E_2), MB_OK); + return FALSE; + +} // ShareNewPathValidate + + +/*+-------------------------------------------------------------------------+ + | ShareNewShareValidate() + | + +-------------------------------------------------------------------------+*/ +BOOL ShareNewShareValidate(HWND hWnd, LPTSTR ShareName) { + ULONG i; + VIRTUAL_SHARE_BUFFER *VShare; + SHARE_BUFFER *VList; + + // Loop through share list seeing if the share already exists (same name) + if (DServ->ShareList != NULL) { + VList = DServ->ShareList->SList; + + for (i = 0; i < DServ->ShareList->Count; i++) + if (!lstrcmpi(VList[i].Name, ShareName)) + goto ShareNewShareVFail; + + } + + // Now do the same for the virtual share list + VShare = DServ->VShareStart; + while (VShare) { + + if (!lstrcmpi(VShare->Name, ShareName)) + goto ShareNewShareVFail; + + VShare = VShare->next; + } + + return TRUE; + +ShareNewShareVFail: + MessageBox(hWnd, Lids(IDS_E_4), Lids(IDS_E_2), MB_OK); + return FALSE; + +} // ShareNewShareValidate + + +/*+-------------------------------------------------------------------------+ + | NWShareNew() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK NWShareNew(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + BOOL Enable; + int wmId, wmEvent; + TCHAR Path[MAX_PATH + 1]; + TCHAR NewShare[MAX_SHARE_NAME_LEN + 1]; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *Drive; + BOOL ok; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_SHARE_NAME_LEN, 0); + hCtrl = GetDlgItem(hDlg, IDC_EDIT2); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PATH, 0); + + if (NewShareType == SELECT_TYPE_MODIFY) { + SendMessage(hDlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) Lids(IDS_D_5)); + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + EnableWindow(hCtrl, FALSE); + ShowWindow(hCtrl, SW_HIDE); + + hCtrl = GetDlgItem(hDlg, IDC_SHARENAME); + if (CurrentDShare->VFlag) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentDShare; + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) VShare->Name); + } else + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) CurrentDShare->Name); + + } else { + hCtrl = GetDlgItem(hDlg, IDC_SHARENAME); + EnableWindow(hCtrl, FALSE); + ShowWindow(hCtrl, SW_HIDE); + + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, FALSE); + } + + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + + case IDOK: + ok = TRUE; + + if (NewShareType == SELECT_TYPE_ADD) { + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + * (WORD *)NewShare = sizeof(NewShare); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) NewShare); + + if (!ShareNewShareValidate(hDlg, NewShare)) + ok = FALSE; + } + + if (ok) { + hCtrl = GetDlgItem(hDlg, IDC_EDIT2); + * (WORD *)Path = sizeof(Path); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) Path); + + if (!ShareNewPathValidate(hDlg, Path, &Drive)) + ok = FALSE; + } + + if (ok) { + if (NewShareType == SELECT_TYPE_ADD) { + // If we are in ADD - then we might have added a virtual + // share when we did the match, if so get rid of it... + if ((CurrentShare !=NULL) && (CurrentShare->DestShare != NULL)) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + VShareListDelete(DServ, VShare); + CurrentShare->DestShare = NULL; + } + + // Got rid of old one, now need to create new one. + CurrentShare->Virtual = TRUE; + VShare = VShareListAdd(DServ, NewShare, Path); + VShare->Drive = Drive; + VShare->UseCount++; + CurrentShare->DestShare = (SHARE_BUFFER *) VShare; + CurrentDShare = (SHARE_BUFFER *) VShare; + } else + // Modify so update the values of the path/drive with + // the new stuff. + if ((CurrentShare !=NULL) && (CurrentShare->DestShare != NULL)) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + lstrcpy(VShare->Path, Path); + VShare->Drive = Drive; + } + + + EndDialog(hDlg, 0); + } + + break; + + case IDCANCEL: + EndDialog(hDlg, 0); + break; + + case IDHELP: + if (NewShareType == SELECT_TYPE_MODIFY) + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_SHAREPROP); + else + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_SHARENEW); + + break; + + case ID_INIT: + // Modify should only be for a virtual share + if (NewShareType == SELECT_TYPE_MODIFY) { + hCtrl = GetDlgItem(hDlg, IDC_EDIT2); + if (CurrentDShare->VFlag) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentDShare; + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) VShare->Path); + } + } + + case IDC_EDIT1: + case IDC_EDIT2: + if (wmEvent == EN_CHANGE) { + Enable = TRUE; + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + + if (NewShareType == SELECT_TYPE_ADD) + if (!SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) + Enable = FALSE; + + hCtrl = GetDlgItem(hDlg, IDC_EDIT2); + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0) < 3) + Enable = FALSE; + + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, Enable); + + } + break; + + } + return TRUE; + + } + + return (FALSE); // Didn't process the message + + lParam; +} // NWShareNew + + +/*+-------------------------------------------------------------------------+ + | NWShareNew_Do() + | + +-------------------------------------------------------------------------+*/ +void NWShareNew_Do(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance( (DLGPROC) NWShareNew, hInst); + DialogBox(hInst, TEXT("NWShareAdd"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // NWShareNew_Do + + +/*+-------------------------------------------------------------------------+ + | Add / Modify Share Selection Dialog Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | FixShare() + | + +-------------------------------------------------------------------------+*/ +void FixShare(LPTSTR OrigShare, LPTSTR ServName, LPTSTR DestShare) { + LPTSTR pShare = OrigShare; + + lstrcpy(DestShare, TEXT("")); + + // Assume it is in the form \\server\share + // Skip over leading double-back for server + if ((pShare[0] == '\\') && (pShare[1] == '\\')) + pShare+= 2; + + // Now skip over the server name + while (*pShare && (*pShare != '\\')) + pShare++; + + // pShare should point to the share-name, append this to the server-name + if (*ServName != '\\') + lstrcat(DestShare, TEXT("\\\\")); + + lstrcat(DestShare, ServName); + lstrcat(DestShare, pShare); + +} // FixShare + + +/*+-------------------------------------------------------------------------+ + | NTShareListFill() + | + +-------------------------------------------------------------------------+*/ +void NTShareListFill(HWND hDlg) { + HWND hCtrl; + SHARE_LIST *ShareList = NULL; + SHARE_BUFFER *SList; + DWORD i, dwIndex; + BOOL Match = FALSE; + VIRTUAL_SHARE_BUFFER *VShare; + + // Clear it out + hCtrl = GetDlgItem(hDlg, IDC_COMBO2); + SendMessage(hCtrl, CB_RESETCONTENT, 0, 0L); + + // First enum all the regular shares + ShareList = DServ->ShareList; + if (ShareList != NULL) { + SList = ShareList->SList; + + for (i = 0; i < ShareList->Count; i++) { + dwIndex = SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) SList[i].Name); + SendMessage(hCtrl, CB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) &SList[i]); + } + + } + + // Now enum all the virtual shares + VShare = DServ->VShareStart; + while (VShare) { + dwIndex = SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) VShare->Name); + SendMessage(hCtrl, CB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) VShare); + VShare = VShare->next; + } + + // Match the combo-box to the given share + if (CurrentShare->DestShare != NULL) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + SendMessage(hCtrl, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) VShare->Name); + } else + SendMessage(hCtrl, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) CurrentShare->DestShare->Name); + +} // NTShareListFill + + +/*+-------------------------------------------------------------------------+ + | NWShareSelect() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK NWShareSelect(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + static TCHAR ServName[MAX_UNC_PATH+1]; + VIRTUAL_SHARE_BUFFER *VShare; + SHARE_BUFFER *OrigShare = NULL; + SHARE_BUFFER *NewShare; + HWND hCtrl; + DWORD dwData, dwIndex; + int wmId, wmEvent; + ULONG i; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + if (SelectType == SELECT_TYPE_MODIFY) { + SendMessage(hDlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) Lids(IDS_D_6)); + // Disable Source combo box... + hCtrl = GetDlgItem(hDlg, IDC_COMBO1); + EnableWindow(hCtrl, FALSE); + ShowWindow(hCtrl, SW_HIDE); + OrigShare = CurrentShare->DestShare; + } + + hCtrl = GetDlgItem(hDlg, IDC_FSERVER); + lstrcpy(ServName, Lids(IDS_D_7)); + lstrcat(ServName, SServ->Name); + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) ServName); + + hCtrl = GetDlgItem(hDlg, IDC_TSERVER); + lstrcpy(ServName, Lids(IDS_D_8)); + lstrcat(ServName, DServ->Name); + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) ServName); + + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PATH, 0); + + if (SelectType == SELECT_TYPE_MODIFY) + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) CurrentShare->SubDir); + + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + + case IDOK: + CurrentShare->Convert = TRUE; // only really needed for add + + hCtrl = GetDlgItem(hDlg, IDC_COMBO2); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0L); + + if (dwIndex != CB_ERR) { + dwData = SendMessage(hCtrl, CB_GETITEMDATA, dwIndex, 0L); + NewShare = (SHARE_BUFFER *) dwData; + + if (OrigShare != NewShare) { + CurrentShare->DestShare = NewShare; + + // this is actually a flag for the destination share + CurrentShare->Virtual = NewShare->VFlag; + } + } + + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + * (WORD *)CurrentShare->SubDir = sizeof(CurrentShare->SubDir); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) CurrentShare->SubDir); + + EndDialog(hDlg, 0); + break; + + case IDCANCEL: + if (SelectType == SELECT_TYPE_ADD) { + + // If we are in ADD - then we might have added a virtual + // share when we did the match, if so get rid of it... + if ((CurrentShare !=NULL) && (CurrentShare->DestShare != NULL)) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + VShareListDelete(DServ, VShare); + CurrentShare->DestShare = NULL; + } + + CurrentShare = NULL; + } + + EndDialog(hDlg, 0); + break; + + case IDHELP: + if (SelectType == SELECT_TYPE_MODIFY) + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_SHAREMOD); + else + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_SHAREADD); + break; + + case IDC_NEWSHARE: + CurrentDShare = NULL; + NewShareType = SELECT_TYPE_ADD; + NWShareNew_Do(hDlg); + + // Match the combo-box to the given share + NTShareListFill(hDlg); + PostMessage(hDlg, WM_COMMAND, ID_UPDATECOMBO, 0L); + break; + + case IDC_PROPERTIES: + NewShareType = SELECT_TYPE_MODIFY; + hCtrl = GetDlgItem(hDlg, IDC_COMBO2); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0L); + + if (dwIndex != CB_ERR) { + dwData = SendMessage(hCtrl, CB_GETITEMDATA, dwIndex, 0L); + CurrentDShare = (SHARE_BUFFER *) dwData; + NWShareNew_Do(hDlg); + } + + break; + + case ID_INIT: + if (SelectType == SELECT_TYPE_ADD) { + hCtrl = GetDlgItem(hDlg, IDC_COMBO1); + + if (ShareList == NULL) + break; + + CurrentShare = NULL; + for (i = 0; i < ShareList->Count; i++) + if (!SList[i].Convert) { + if (CurrentShare == NULL) + CurrentShare = &SList[i]; + + dwIndex = SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) SList[i].Name); + SendMessage(hCtrl, CB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) &SList[i]); + } + + if (CurrentShare != NULL) { + SendMessage(hCtrl, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) CurrentShare->Name); + MapShare(CurrentShare, DServ); + } + + } else { + // Display the static text + hCtrl = GetDlgItem(hDlg, IDC_VOLUME); + EnableWindow(hCtrl, TRUE); + ShowWindow(hCtrl, SW_SHOW); + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) CurrentShare->Name); + } + + NTShareListFill(hDlg); + PostMessage(hDlg, WM_COMMAND, ID_UPDATECOMBO, 0L); + break; + + // Used to update which volume we are pointing at + case ID_UPDATELIST: + // We might have added a virtual share when we did the + // match, if so get rid of it... + if ((CurrentShare !=NULL) && (CurrentShare->DestShare != NULL)) + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + VShareListDelete(DServ, VShare); + CurrentShare->DestShare = NULL; + } + + hCtrl = GetDlgItem(hDlg, IDC_COMBO1); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0L); + + if (dwIndex != CB_ERR) { + dwData = SendMessage(hCtrl, CB_GETITEMDATA, dwIndex, 0L); + CurrentShare = (SHARE_BUFFER *) dwData; + + // Now need to map this to a new share + if (CurrentShare != NULL) { + MapShare(CurrentShare, DServ); + + // Match the combo-box to the given share + NTShareListFill(hDlg); + } + } + + break; + + // updateded the share list selection + case ID_UPDATECOMBO: + hCtrl = GetDlgItem(hDlg, IDC_COMBO2); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0L); + + if (dwIndex != CB_ERR) { + dwData = SendMessage(hCtrl, CB_GETITEMDATA, dwIndex, 0L); + CurrentDShare = (SHARE_BUFFER *) dwData; + hCtrl = GetDlgItem(hDlg, IDC_PROPERTIES); + + if (CurrentDShare->VFlag) { + EnableWindow(hCtrl, TRUE); + } else { + EnableWindow(hCtrl, FALSE); + } + + } + break; + + case IDC_COMBO1: + if (wmEvent == CBN_SELCHANGE) + PostMessage(hDlg, WM_COMMAND, ID_UPDATELIST, 0L); + + break; + + case IDC_COMBO2: + if (wmEvent == CBN_SELCHANGE) + PostMessage(hDlg, WM_COMMAND, ID_UPDATECOMBO, 0L); + + break; + } + return TRUE; + + } + + return (FALSE); // Didn't process the message + + lParam; +} // NWShareSelect + + +/*+-------------------------------------------------------------------------+ + | ShareSelect_Do() + | + +-------------------------------------------------------------------------+*/ +void NWShareSelect_Do(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC)NWShareSelect, hInst); + DialogBox(hInst, TEXT("NWShareSelect"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // NWShareSelect_Do + + +/*+-------------------------------------------------------------------------+ + | Main File Options Dialog Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | FileOptionsToggleControls() + | + +-------------------------------------------------------------------------+*/ +void FileOptionsToggleControls(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDC_DELETE); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_MODIFY); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_FILES); + EnableWindow(hCtrl, Toggle); + +} // FileOptionsToggleControls + + +/*+-------------------------------------------------------------------------+ + | FileDialogToggle() + | + +-------------------------------------------------------------------------+*/ +void FileDialogToggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + EnableWindow(hCtrl, Toggle); + FileOptionsToggleControls(hDlg, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_ADD); + if (Toggle == FALSE) + EnableWindow(hCtrl, FALSE); + else + if (ShareList && ShareList->Count != ShareList->ConvertCount) + EnableWindow(hCtrl, TRUE); + else + EnableWindow(hCtrl, FALSE); + +} // FileDialogToggle + + +/*+-------------------------------------------------------------------------+ + | DlgFileOptions_Save() + | + +-------------------------------------------------------------------------+*/ +void DlgFileOptions_Save(HWND hDlg) { + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDC_CHKFILES); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + FileOptions->TransferFileInfo = TRUE; + else + FileOptions->TransferFileInfo = FALSE; + +} // DlgFileOptions_Save + + +/*+-------------------------------------------------------------------------+ + | DlgFileOptions_Setup() + | + +-------------------------------------------------------------------------+*/ +void DlgFileOptions_Setup(HWND hDlg) { + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDC_CHKFILES); + if (FileOptions->TransferFileInfo) { + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + FileDialogToggle(hDlg, TRUE); + } else { + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + FileDialogToggle(hDlg, FALSE); + } + +} // DlgFileOptions_Setup + + +/*+-------------------------------------------------------------------------+ + | DlgFileOptions_ListboxAdd() + | + +-------------------------------------------------------------------------+*/ +void DlgFileOptions_ListboxAdd(HWND hDlg, SHARE_BUFFER *CurrentShare, DWORD *wItem, BOOL Insert ) { + HWND hCtrl; + static TCHAR AddLine[256]; + VIRTUAL_SHARE_BUFFER *VShare; + DWORD wItemNum; + + wItemNum = *wItem; + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + if (CurrentShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) CurrentShare->DestShare; + wsprintf(AddLine, TEXT("%s\\%s:\t\\\\%s\\%s\t"), SServ->Name, CurrentShare->Name, DServ->Name, VShare->Name); + } else + wsprintf(AddLine, TEXT("%s\\%s:\t\\\\%s\\%s\t"), SServ->Name, CurrentShare->Name, DServ->Name, CurrentShare->DestShare->Name); + + if (Insert) + ColumnLB_InsertString(hCtrl, wItemNum, AddLine); + else + wItemNum = ColumnLB_AddString(hCtrl, AddLine); + + ColumnLB_SetItemData(hCtrl, wItemNum, (DWORD) CurrentShare); + *wItem = wItemNum; + +} // DlgFileOptions_ListboxAdd + + +/*+-------------------------------------------------------------------------+ + | DlgFileOptions() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgFileOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + DWORD wItemNum; + DWORD dwData; + static short FilesTab, FileOptionsTab; + int wmId, wmEvent; + ULONG i; + SHARE_BUFFER *pShare; + VIRTUAL_SHARE_BUFFER *VShare; + RECT rc; + int TabStop; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + GetClientRect(hCtrl, &rc); + + // Size is half width of listbox - vertical scrollbar + TabStop = (((rc.right - rc.left) - GetSystemMetrics(SM_CXVSCROLL)) / 2); + ColumnLB_SetNumberCols(hCtrl, 2); + ColumnLB_SetColTitle(hCtrl, 0, Lids(IDS_D_9)); + ColumnLB_SetColTitle(hCtrl, 1, Lids(IDS_D_10)); + ColumnLB_SetColWidth(hCtrl, 0, TabStop); + + // Calculate 2nd this way instead of just using TabStop to get rid of roundoff + ColumnLB_SetColWidth(hCtrl, 1, (rc.right - rc.left) - TabStop); + + DlgFileOptions_Setup(hDlg); + + // Fill listbox and set selection (is assumed there is always a selection)... + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + DlgFileOptions_Save(hDlg); + FileOptionsDefaultsSet(FileOptions); + EndDialog(hDlg, 0); + return (TRUE); + + case IDCANCEL: + EndDialog(hDlg, 0); + return (TRUE); + + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_FILE); + return (TRUE); + + case IDC_CHKFILES: + hCtrl = GetDlgItem(hDlg, IDC_CHKFILES); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + FileDialogToggle(hDlg, TRUE); + else + FileDialogToggle(hDlg, FALSE); + + return (TRUE); + + case IDC_ADD: + SelectType = SELECT_TYPE_ADD; + CurrentShare = NULL; + NWShareSelect_Do(hDlg); + + if (CurrentShare != NULL) { + DlgFileOptions_ListboxAdd(hDlg, CurrentShare, &wItemNum, FALSE ); + + // Check if Add button needs to be disabled + ShareList->ConvertCount++; + if (ShareList->Count == ShareList->ConvertCount) { + hCtrl = GetDlgItem(hDlg, IDC_ADD); + EnableWindow(hCtrl, FALSE); + } + + // Buttons need to be re-enabled + FileOptionsToggleControls(hDlg, TRUE); + + // Now make sure focus is set + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + ColumnLB_SetCurSel(hCtrl, wItemNum); + wItemNum = ColumnLB_GetCurSel(hCtrl); + if (wItemNum == LB_ERR) + ColumnLB_SetCurSel(hCtrl, 0); + + }; + + return (TRUE); + + case IDC_DELETE: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = ColumnLB_GetCurSel(hCtrl); + if (wItemNum != LB_ERR) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + pShare = (SHARE_BUFFER *)dwData; + pShare->Convert = FALSE; + ShareList->ConvertCount--; + + // Now need to delete dest share, or reduce use count + if (pShare->DestShare != NULL) + if (pShare->Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) pShare->DestShare; + VShareListDelete(DServ, VShare); + pShare->DestShare = NULL; + } + + ColumnLB_DeleteString(hCtrl, wItemNum); + } + + if (!ShareList->ConvertCount) + FileOptionsToggleControls(hDlg, FALSE); + else { + wItemNum = ColumnLB_GetCurSel(hCtrl); + if (wItemNum == LB_ERR) + ColumnLB_SetCurSel(hCtrl, 0); + } + + if (ShareList->Count != ShareList->ConvertCount) { + hCtrl = GetDlgItem(hDlg, IDC_ADD); + EnableWindow(hCtrl, TRUE); + } + + return (TRUE); + + case IDC_MODIFY: + SelectType = SELECT_TYPE_MODIFY; + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = ColumnLB_GetCurSel(hCtrl); + if (wItemNum != LB_ERR) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + CurrentShare = (SHARE_BUFFER *)dwData; + NWShareSelect_Do(hDlg); + + // Now update listbox to reflect any changes + ColumnLB_DeleteString(hCtrl, wItemNum); + + DlgFileOptions_ListboxAdd(hDlg, CurrentShare, &wItemNum, TRUE ); + + // now reset focus back to this item + ColumnLB_SetCurSel(hCtrl, wItemNum); + } + return (TRUE); + + case IDC_FILES: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = ColumnLB_GetCurSel(hCtrl); + if (wItemNum != LB_ERR) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + CurrentShare = (SHARE_BUFFER *)dwData; + FileSelect_Do(hDlg, SServ, CurrentShare); + } + return (TRUE); + + case IDC_FOPTIONS: + return (TRUE); + + case ID_INIT: + + if (ShareList != NULL) { + SList = ShareList->SList; + + for (i = 0; i < ShareList->Count; i++) + if (SList[i].Convert) { + DlgFileOptions_ListboxAdd(hDlg, &SList[i], &wItemNum, FALSE ); + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + ColumnLB_SetCurSel(hCtrl, 0); + } + + if (ShareList->Count == ShareList->ConvertCount) { + hCtrl = GetDlgItem(hDlg, IDC_ADD); + EnableWindow(hCtrl, FALSE); + } + + if (!ShareList->ConvertCount) + FileOptionsToggleControls(hDlg, FALSE); + + } else + FileOptionsToggleControls(hDlg, FALSE); + + return (TRUE); + + case IDC_LIST1: + switch (wmEvent) { + case LBN_DBLCLK: + PostMessage(hDlg, WM_COMMAND, IDC_MODIFY, 0L); + break; + + case LBN_SELCHANGE: + if (!ShareList || !ShareList->ConvertCount) + FileOptionsToggleControls(hDlg, TRUE); + + break; + + } + break; + + } + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgFileOptions + + +/*+-------------------------------------------------------------------------+ + | FileOptions_Do() + | + +-------------------------------------------------------------------------+*/ +void FileOptions_Do(HWND hDlg, void *ConvOptions, SOURCE_SERVER_BUFFER *SourceServer, DEST_SERVER_BUFFER *DestServer) { + DLGPROC lpfnDlg; + + SServ = SourceServer; + DServ = DestServer; + + NWServerFree(); + NWServerSet(SourceServer->Name); + NTServerSet(DestServer->Name); + FileOptions = (FILE_OPTIONS *) ConvOptions; + ShareList = SServ->ShareList; + + lpfnDlg = MakeProcInstance((DLGPROC)DlgFileOptions, hInst); + DialogBox(hInst, TEXT("FileMain"), hDlg, lpfnDlg) ; + + FreeProcInstance(lpfnDlg); +} // FileOptions_Do diff --git a/private/nw/convert/nwconv/filedlg.h b/private/nw/convert/nwconv/filedlg.h new file mode 100644 index 000000000..fbadf75db --- /dev/null +++ b/private/nw/convert/nwconv/filedlg.h @@ -0,0 +1,34 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _FILEDLG_ +#define _FILEDLG_ + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef struct _FILE_OPTIONS { + BOOL TransferFileInfo; + BOOL Validated; // Has user validated our mappings? +} FILE_OPTIONS; + + +void FileOptions_Do(HWND hDlg, void *ConvOptions, SOURCE_SERVER_BUFFER *SourceServ, DEST_SERVER_BUFFER *DestServ); +void FileOptionsInit(void **lpfo); +void FileOptionsDefaultsReset(); +void FileOptionsLoad(HANDLE hFile, void **lpfo); +void FileOptionsSave(HANDLE hFile, void *fo); + +// These are actually in filesel.h - but for simplicity put them here +void FillDirInit(); +void TreeFillRecurse(UINT Level, LPTSTR Path, DIR_BUFFER *Dir); +void TreeCompact(DIR_BUFFER *Dir); +void TreeRootInit(SHARE_BUFFER *CShare, LPTSTR NewPath); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/fileicon.bmp b/private/nw/convert/nwconv/fileicon.bmp new file mode 100644 index 000000000..39afde299 Binary files /dev/null and b/private/nw/convert/nwconv/fileicon.bmp differ diff --git a/private/nw/convert/nwconv/filesel.c b/private/nw/convert/nwconv/filesel.c new file mode 100644 index 000000000..8d8b8161a --- /dev/null +++ b/private/nw/convert/nwconv/filesel.c @@ -0,0 +1,2349 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + FileSel.c + +Abstract: + + Handles processing for the file selection listbox. This is a + hierarchical file/directory tree with checkboxes besides the files + and directories. + + If the checkbox is checked then that file or directory will be + copied, otherwise it won't. There are some directories that are + excluded by default. These are directories on the NW server that + are known to contain binaries that are not needed on the NT side + (such as the NetWare administration tools). + +Author: + + Arthur Hanson (arth) 10-Feb-1994 + +Revision History: + +--*/ + +#include "globals.h" + +#include "hierfile.h" +#include "nwconv.h" +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "columnlb.h" +#include "statbox.h" +#include "userdlg.h" + +#include // For pow function + +#define X_BORDER 10 +#define Y_BORDER 10 +#define SPLITTER_WIDTH 3 +#define BUTTON_Y_BORDER 6 +#define BUTTON_X_BORDER 10 + +static int List1Width; +static int Splitter_Left; +static int Splitter_Bottom; +static HCURSOR CursorSplitter; +static HWND hwndList2 = 0; +static HWND hwndList1 = 0; + +static SHARE_BUFFER *CurrentShare; +static SOURCE_SERVER_BUFFER *SServ; +static BOOL HiddenFiles = FALSE; +static BOOL SystemFiles = FALSE; +static DIR_BUFFER *oDir = NULL; + +static ULONG TotalFileSize = 0; +static LPARAM mouseHit = 0; +static WORD LastFocus = 0; +static HWND ListFocus = NULL; + +static ULONG TCount; + +static WNDPROC _wpOrigWndProc; +static WNDPROC _wpOrigWndProc2; + + +HEIRDRAWSTRUCT HierDrawStruct; +BOOL SysDir = FALSE; + +#define ROWS 2 +#define COLS 2 + +// define a scratch buffer for quickly building up dir/file lists +#define DEF_NUM_RECS 50 +#define DEF_REC_DELTA 25 +static UINT BufferSize = 0; +static WIN32_FIND_DATA *ffd = NULL; + + +/*+-------------------------------------------------------------------------+ + | Routines for Directory/File Trees | + +-------------------------------------------------------------------------+*/ + + +///////////////////////////////////////////////////////////////////////// +FILE_PATH_BUFFER * +FilePathInit() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + FILE_PATH_BUFFER *fpBuf = NULL; + + fpBuf = AllocMemory(sizeof(FILE_PATH_BUFFER)); + if (fpBuf == NULL) + return NULL; + + memset(fpBuf, 0, sizeof(FILE_PATH_BUFFER)); + return fpBuf; + +} // FilePathInit + + +///////////////////////////////////////////////////////////////////////// +VOID +FilePathServerSet( + FILE_PATH_BUFFER *fpBuf, + LPTSTR Server + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + fpBuf->Server = Server; + + if (fpBuf->Server == NULL) + return; + + wsprintf(fpBuf->FullPath, TEXT("\\\\%s\\"), Server); + +} // FilePathServerSet + + +///////////////////////////////////////////////////////////////////////// +VOID +FilePathShareSet( + FILE_PATH_BUFFER *fpBuf, + LPTSTR Share + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + fpBuf->Share = Share; + if ((fpBuf->Server == NULL) || (fpBuf->Share == NULL)) + return; + + wsprintf(fpBuf->FullPath, TEXT("\\\\%s\\%s"), fpBuf->Server, Share); + fpBuf->Path = &fpBuf->FullPath[lstrlen(fpBuf->FullPath)]; + +} // FilePathShareSet + + +///////////////////////////////////////////////////////////////////////// +VOID +FilePathPathSet( + FILE_PATH_BUFFER *fpBuf, + LPTSTR Path + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + if ((fpBuf->Server == NULL) || (fpBuf->Share == NULL)) + return; + + *fpBuf->Path = TEXT('\0'); + if (Path == NULL) + return; + + lstrcat(fpBuf->FullPath, Path); + +} // FilePathPathSet + + + +///////////////////////////////////////////////////////////////////////// +VOID +TreeDelete( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + Walks an in-memory directory tree and free's up all the memory associated + with it and all child nodes. + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_BUFFER *DList; + ULONG i; + + if (Dir == NULL) + return; + + if (Dir->DirList) { + DList = Dir->DirList->DirBuffer; + for (i = 0; i < Dir->DirList->Count; i++) + TreeDelete(&DList[i]); + + FreeMemory(Dir->DirList); + } + + if (Dir->FileList) + FreeMemory(Dir->FileList); + +} // TreeDelete + + +///////////////////////////////////////////////////////////////////////// +VOID +TreePrune( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + Prunes a tree down by removing un-needed nodes. If a node is marked + as CONVERT_ALL or CONVERT_NONE then we don't need any of the child + leaves as we know these will be the same. Only CONVERT_PARTIAL + needs to be saved. + + This is used so we only copy/save the minimum needed. + +Arguments: + + +Return Value: + + +--*/ + +{ + BYTE Convert; + DIR_BUFFER *DList; + ULONG i; + + if (Dir == NULL) + return; + + // First visit all of the children sub-dirs and prune them. Next: + // if partial convert then we can't delete this node, else we can + // clean up all the children - we leave it to the parent node to + // delete the current node. + Convert = Dir->Convert; + if (Dir->DirList) { + DList = Dir->DirList->DirBuffer; + for (i = 0; i < Dir->DirList->Count; i++) + TreePrune(&DList[i]); + + if (Convert == CONVERT_PARTIAL) + return; + + if (Dir->Special && (Convert == CONVERT_ALL)) + return; + + for (i = 0; i < Dir->DirList->Count; i++) + TreeDelete(&DList[i]); + + Dir->DirList = NULL; + } + + if (Convert == CONVERT_PARTIAL) + return; + + if (Dir->FileList) + FreeMemory(Dir->FileList); + + Dir->FileList = NULL; + +} // TreePrune + + +///////////////////////////////////////////////////////////////////////// +VOID +_TreeCountR( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + Count all the files under a sub-dir. This recuses down all the child + nodes. + +Arguments: + + +Return Value: + + +--*/ + +{ + BYTE Convert; + DIR_BUFFER *DList; + ULONG i; + + if ((Dir == NULL) || (!Dir->Convert)) + return; + + Convert = Dir->Convert; + if (Dir->DirList) { + DList = Dir->DirList->DirBuffer; + for (i = 0; i < Dir->DirList->Count; i++) + _TreeCountR(&DList[i]); + + } + + if (Dir->FileList) + for (i = 0; i < Dir->FileList->Count; i++) + if (Dir->FileList->FileBuffer[i].Convert) + TCount++; + +} // _TreeCountR + + +ULONG TreeCount(DIR_BUFFER *Dir) { + TCount = 0; + if (Dir == NULL) + return TCount; + + _TreeCountR(Dir); + return TCount; + +} // TreeCount + + +///////////////////////////////////////////////////////////////////////// +VOID +_TreeCopyR( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + Duplicates a directory/File tree structure in memory. + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_LIST *DList; + DIR_BUFFER *DBuff; + FILE_LIST *FList; + FILE_BUFFER *FBuff; + ULONG Size; + ULONG i; + + if (Dir == NULL) + return; + + if (Dir->FileList) { + // Create clone of file list + Size = sizeof(FILE_LIST) + (sizeof(FILE_BUFFER) * Dir->FileList->Count); + FList = AllocMemory(Size); + + if (FList != NULL) + memcpy(FList, Dir->FileList, Size); + + // Copied it, now fixup the internal pointers. + FList->parent = Dir; + + FBuff = FList->FileBuffer; + for (i = 0; i < FList->Count; i++) + FBuff[i].parent = FList; + + // Now replace pointer with cloned tree + Dir->FileList = FList; + } + + if (Dir->DirList) { + // Create clone of Dir List + Size = sizeof(DIR_LIST) + (sizeof(DIR_BUFFER) * Dir->DirList->Count); + DList = AllocMemory(Size); + + if (DList != NULL) + memcpy(DList, Dir->DirList, Size); + + // Copied it, now fixup the internal pointers. + DList->parent = Dir; + + DBuff = DList->DirBuffer; + for (i = 0; i < DList->Count; i++) + DBuff[i].parent = DList; + + // Now replace pointer with cloned tree + Dir->DirList = DList; + + // Now recurse into children and fix them up + for (i = 0; i < DList->Count; i++) + _TreeCopyR(&DBuff[i]); + + } + +} // _TreeCopyR + + +///////////////////////////////////////////////////////////////////////// +DIR_BUFFER * +TreeCopy( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_BUFFER *nDir = NULL; + + if (Dir == NULL) + return NULL; + + nDir = AllocMemory(sizeof(DIR_BUFFER)); + if (nDir != NULL) { + memcpy(nDir, Dir, sizeof(DIR_BUFFER)); + _TreeCopyR(nDir); + } + + return nDir; + +} // TreeCopy + + + +///////////////////////////////////////////////////////////////////////// +int __cdecl +FileBufferCompare( + const VOID *arg1, + const VOID *arg2 + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + WIN32_FIND_DATA *Farg1, *Farg2; + + Farg1 = (WIN32_FIND_DATA *) arg1; + Farg2 = (WIN32_FIND_DATA *) arg2; + + // This works as the first item of the structure is the string + return lstrcmpi( Farg1->cFileName, Farg2->cFileName); + +} // FileBufferCompare + + +///////////////////////////////////////////////////////////////////////// +VOID +DirAdjustConvert( + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + Need to adjust convert flag (none, full, partial) down the tree to the + root. + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL Partial = FALSE; + ULONG ChildCount = 0; + ULONG ChildSelected = 0; + DIR_LIST *DirList = NULL; + FILE_LIST *FileList = NULL; + ULONG i; + + if (Dir == NULL) + return; + + // if no files or dirs don't try to re-adjust current setting. + if ((Dir->DirList == NULL) && (Dir->FileList == NULL)) + goto DirAdjRecurse; + + // Scan the children directories to see what is to be converted. + DirList = Dir->DirList; + if (DirList != NULL) { + ChildCount += DirList->Count; + for (i = 0; i < DirList->Count; i++) + if (DirList->DirBuffer[i].Convert == CONVERT_PARTIAL) + Partial = TRUE; + else + ChildSelected += DirList->DirBuffer[i].Convert; + } + + // if any of the children were partial convert then it is easy, as + // we are partial convert as well. + if (Partial) { + Dir->Convert = CONVERT_PARTIAL; + goto DirAdjRecurse; + } + + + // Scan the children files to see what is to be converted. + FileList = Dir->FileList; + if (FileList != NULL) { + ChildCount += FileList->Count; + for (i = 0; i < FileList->Count; i++) + ChildSelected += FileList->FileBuffer[i].Convert; + } + + if (ChildSelected == ChildCount) + Dir->Convert = CONVERT_ALL; + else + if (ChildSelected == 0) + Dir->Convert = CONVERT_NONE; + else + Dir->Convert = CONVERT_PARTIAL; + +DirAdjRecurse: + DirList = Dir->parent; + if (DirList != NULL) + DirAdjustConvert(DirList->parent); + +} // DirAdjustConvert + + +///////////////////////////////////////////////////////////////////////// +VOID +DirAdjustConvertChildren( + DIR_BUFFER *Dir, + BYTE Convert + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_LIST *DirList = NULL; + FILE_LIST *FileList = NULL; + ULONG i; + + if (Dir == NULL) + return; + + Dir->Convert = Convert; + + // Scan the children files + FileList = Dir->FileList; + if (FileList != NULL) + for (i = 0; i < FileList->Count; i++) + FileList->FileBuffer[i].Convert = Convert; + + // Scan the children directories + DirList = Dir->DirList; + if (DirList != NULL) + for (i = 0; i < DirList->Count; i++) + DirAdjustConvertChildren(&DirList->DirBuffer[i], Convert); + +} // DirAdjustConvertChildren + + +///////////////////////////////////////////////////////////////////////// +BOOL +SubdirRestrict( + LPTSTR Path, + LPTSTR Subdir + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + ULONG i = 0; + LPTSTR RestrictPath[5]; + CONVERT_OPTIONS * ConvertOptions; + + // if the user has specified the 'transfer netware specific info' + // option the we should transfer the mail directory by default... + ConvertOptions = (CONVERT_OPTIONS *)CurrentConvertList->ConvertOptions; + + if (ConvertOptions->NetWareInfo) + RestrictPath[i++] = Lids(IDS_S_3); + + RestrictPath[i++] = Lids(IDS_S_2); + RestrictPath[i++] = Lids(IDS_S_4); + RestrictPath[i++] = Lids(IDS_S_5); + RestrictPath[i++] = NULL; + + i = 0; + while(RestrictPath[i] != NULL) { + if (!lstrcmpi(RestrictPath[i], Subdir)) + return TRUE; + + i++; + } + + return FALSE; + +} // SubdirRestrict + + +///////////////////////////////////////////////////////////////////////// +VOID +FillDirInit() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + if (ffd == NULL) { + ffd = AllocMemory(sizeof(WIN32_FIND_DATA) * DEF_NUM_RECS); + BufferSize = DEF_NUM_RECS; + } + +} // FillDirInit + + +///////////////////////////////////////////////////////////////////////// +VOID +FillDir( + UINT Level, + LPTSTR Path, + DIR_BUFFER *Dir, + BOOL DoDirs + ) + +/*++ + +Routine Description: + + Given a DIR_BUFFER, enumerate the files and sub-dirs under it and + attach them (one level-deep only). + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_UNC_PATH + 1]; + DIR_LIST *DirList = NULL; + DIR_LIST *OldDirList = NULL; + DIR_BUFFER *DBuff; + + FILE_LIST *FileList = NULL; + FILE_LIST *OldFileList = NULL; + FILE_BUFFER *FBuff; + + HANDLE fHandle = NULL; + ULONG DirCount = 0; + ULONG FileCount = 0; + ULONG Count = 0; + BOOL ret = TRUE; + ULONG i; + BYTE Convert; + BOOL ConvFlag; + + FixPathSlash(NewPath, Path); + lstrcat(NewPath, TEXT("*.*")); + +#ifdef DEBUG +dprintf(TEXT("Working on dir: %u %s\r\n"), Level, Path); +#endif + + Panel_Line(7, TEXT("%s"), Path); + fHandle = FindFirstFile(NewPath, &ffd[Count]); + + ret = (fHandle != INVALID_HANDLE_VALUE); + + // loop filling in the temp buffer - figure out how many dirs and files + // we have to remember - and build up a temporary buffer of them + while (ret) { + + if (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + ConvFlag = TRUE; + + if (!((lstrcmp(ffd[Count].cFileName, TEXT("."))) && (lstrcmp(ffd[Count].cFileName, TEXT(".."))))) + ConvFlag = FALSE; + + if (!HiddenFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + ConvFlag = FALSE; + + if (!SystemFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) + ConvFlag = FALSE; + + // Use the cAlternateFileName as a flag whether to convert + if (ConvFlag) { + ffd[Count].cAlternateFileName[0] = 1; + DirCount++; + } else + ffd[Count].cAlternateFileName[0] = 0; + + } else { + ConvFlag = TRUE; + + if (!HiddenFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + ConvFlag = FALSE; + + if (!SystemFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) + ConvFlag = FALSE; + + if (ConvFlag) { + ffd[Count].cAlternateFileName[0] = 1; + FileCount++; + } else + ffd[Count].cAlternateFileName[0] = 0; + + } + + Count++; + + // check if we are going to run out of space in our buffer - if so + // allocate more space + if (Count >= BufferSize) { + BufferSize += DEF_REC_DELTA; + ffd = ReallocMemory(ffd, sizeof(WIN32_FIND_DATA) * BufferSize); + } + + if (ffd == NULL) { + FindClose(fHandle); + return; + } else + ret = FindNextFile(fHandle, &ffd[Count]); + + } + + FindClose(fHandle); + +#ifdef DEBUG +dprintf(TEXT(" Num Dirs / Files: %li %li\r\n"), DirCount, FileCount); +#endif + + // Temp buffer is all filled in at this point. Sort it first + if (Count != 0) + qsort((void *) ffd, (size_t) Count, sizeof(WIN32_FIND_DATA), FileBufferCompare); + + // Now create the actual list structures + if (DoDirs && DirCount) + DirList = AllocMemory(sizeof(DIR_LIST) + (sizeof(DIR_BUFFER) * DirCount)); + + if (FileCount) + FileList = AllocMemory(sizeof(FILE_LIST) + (sizeof(FILE_BUFFER) * FileCount)); + + // if there is no dirlist and there is an old one, clean up the old-one. + if (DoDirs && (DirList == NULL) && (Dir->DirList != NULL)) { + // save off file list so it isn't nuked + OldFileList = (FILE_LIST *) Dir->FileList; + Dir->FileList = NULL; + TreeDelete(Dir); + Dir->DirList = NULL; + + // Now restore file list + Dir->FileList = OldFileList; + } + + // same for file list. + if ((FileList == NULL) && (Dir->FileList != NULL)) { + FreeMemory(Dir->FileList); + Dir->FileList = NULL; + } + + // If nothing to copy, or couldn't alloc memory then no reason to continue + // further... + if ((DirList == NULL) && (FileList == NULL)) + return; + + if (Dir->Convert == CONVERT_PARTIAL) + Convert = CONVERT_ALL; + else + Convert = Dir->Convert; + + if (DoDirs && (DirList != NULL)) { + DirList->Count = DirCount; + DirList->Level = Level; + DirList->parent = Dir; + DirList->DirBuffer[DirCount - 1].Last = TRUE; + } + + if (FileList != NULL) { + FileList->Count = FileCount; + FileList->parent = Dir; + } + + // transfer the temp buffers to our list structures + DirCount = FileCount = 0; + for (i = 0; i < Count; i++) { + if (ffd[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + // Directories + if (DoDirs) { + // Check our Flag + if (ffd[i].cAlternateFileName[0] == 1) { + DBuff = &DirList->DirBuffer[DirCount]; + DBuff->Attributes = ffd[i].dwFileAttributes; + lstrcpy(DBuff->Name, ffd[i].cFileName); + DBuff->parent = DirList; + + // Check against the subdirs we don't want to convert by default + // if the user has already toggled that these should be converted, + // then the copy of the old info below will fix it back up. + if (SysDir && (Level == 1) && SubdirRestrict(Path, DBuff->Name)) { + DBuff->Convert = CONVERT_NONE; + DBuff->Special = TRUE; + } else + DBuff->Convert = Convert; + + DirCount++; + } + } + } else { + // Files + Panel_Line(8, TEXT("%s"), ffd[i].cFileName); + + // Check our Flag + if (ffd[i].cAlternateFileName[0] == 1) { + FBuff = &FileList->FileBuffer[FileCount]; + FBuff->Attributes = ffd[i].dwFileAttributes; + lstrcpy(FBuff->Name, ffd[i].cFileName); + FBuff->parent = FileList; + FBuff->Convert = Convert; + FBuff->Size = ffd[i].nFileSizeLow; + + TotalFileSize += ffd[i].nFileSizeLow; + Panel_Line(9, TEXT("%s"), lToStr(TotalFileSize)); + FileCount++; + } + } + + } + + + // Now have the new lists filled in. If there was an old list then we must + // now merge ... can we say pain in the #$$ + if (DoDirs) { + OldDirList = (DIR_LIST *) Dir->DirList; + Dir->DirList = DirList; + } + + OldFileList = (FILE_LIST *) Dir->FileList; + Dir->FileList = FileList; + + // Check the directories + if (DoDirs && (OldDirList != NULL) && (DirList != NULL)) { + int cmp; + + DirCount = 0; + i = 0; + + while (i < OldDirList->Count) { + do { + cmp = lstrcmpi(OldDirList->DirBuffer[i].Name, DirList->DirBuffer[DirCount].Name); + + // a match so copy old data into new... + if (!cmp) { + DBuff = &DirList->DirBuffer[DirCount]; + DBuff->Convert = OldDirList->DirBuffer[i].Convert; + DBuff->DirList = OldDirList->DirBuffer[i].DirList; + DBuff->FileList = OldDirList->DirBuffer[i].FileList; + + // Now point these back to the new structures + if (DBuff->DirList) + DBuff->DirList->parent = DBuff; + + if (DBuff->FileList) + DBuff->FileList->parent = DBuff; + } + + // keep incrementing new dir list until we go past old server + // list, then must skip out and increment old server list + DirCount++; + } while ((DirCount < DirList->Count) && (cmp > 0)); + + if (DirCount >= DirList->Count) + break; + + i++; + } + } + + // Same stuff for the files + if ((OldFileList != NULL) && (FileList != NULL)) { + int cmp; + + FileCount = 0; + i = 0; + + while (i < OldFileList->Count) { + do { + cmp = lstrcmpi(OldFileList->FileBuffer[i].Name, FileList->FileBuffer[FileCount].Name); + + // a match so copy old data into new... + if (!cmp) + FileList->FileBuffer[FileCount].Convert = OldFileList->FileBuffer[i].Convert; + + FileCount++; + } while ((FileCount < FileList->Count) && (cmp > 0)); + + if (FileCount >= FileList->Count) + break; + + i++; + } + } + + // Clean up any old lists + if (OldDirList != NULL) + FreeMemory(OldDirList); + + if (OldFileList != NULL) + FreeMemory(OldFileList); + + DirAdjustConvert(Dir); + +} // FillDir + + +///////////////////////////////////////////////////////////////////////// +VOID +_TreeFillRecurse( + UINT Level, + LPTSTR Path, + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR NewPath[MAX_UNC_PATH + 1]; + DIR_LIST *DirList = NULL; + ULONG i; + + FillDir(Level, Path, Dir, TRUE); + DirList = Dir->DirList; + + if (DirList != NULL) + for (i = 0; i < DirList->Count; i++) { + + if (Panel_Cancel()) + return; + + if (DirList->DirBuffer[i].Convert) { + wsprintf(NewPath, TEXT("%s\\%s"), Path, DirList->DirBuffer[i].Name); + _TreeFillRecurse(Level + 1, NewPath, &DirList->DirBuffer[i]); + } + } + +} // _TreeFillRecurse + + +///////////////////////////////////////////////////////////////////////// +VOID +TreeFillRecurse( + UINT Level, + LPTSTR Path, + DIR_BUFFER *Dir + ) +{ + TotalFileSize = 0; + FillDirInit(); + _TreeFillRecurse(Level, Path, Dir); +} // TreeFillRecurse + + +///////////////////////////////////////////////////////////////////////// +ULONG +TotalFileSizeGet() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + return TotalFileSize; +} // TotalFileSizeGet + + +///////////////////////////////////////////////////////////////////////// +VOID +TreeRecurseCurrentShareSet( + SHARE_BUFFER *CShare + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + CurrentShare = CShare; + + SysDir = FALSE; + if (!CShare) + return; + + if (!lstrcmpi(CShare->Name, Lids(IDS_S_6))) + SysDir = TRUE; + + return; + +} // TreeRecurseCurrentShareSet + + +///////////////////////////////////////////////////////////////////////// +VOID + TreeRootInit( + SHARE_BUFFER *CShare, + LPTSTR NewPath + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TreeRecurseCurrentShareSet(CShare); + + if (CShare->Root) + return; + + CShare->Root = AllocMemory(sizeof(DIR_BUFFER)); + lstrcpy(CShare->Root->Name, NewPath); + CShare->Root->Last = TRUE; + CShare->Root->Attributes = FILE_ATTRIBUTE_DIRECTORY; + + CShare->Root->DirList = NULL; + CShare->Root->FileList = NULL; + CShare->Root->parent = NULL; + + // have to set this to preserve user selection of special excluded dirs... + if (SysDir) + CShare->Root->Special = TRUE; + + CShare->Root->Convert = CONVERT_ALL; + + FillDir(1, CShare->Root->Name, CShare->Root, TRUE); + DirAdjustConvert(CShare->Root); + +} // TreeRootInit + + +///////////////////////////////////////////////////////////////////////// +VOID +ControlsResize( + HWND hDlg, + int Height, + int Width + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + HWND hCtrl; + int nHeight, nWidth, BtnWidth, BtnHeight; + RECT rc; + + hCtrl = GetDlgItem(hDlg, IDOK); + GetWindowRect(hCtrl, &rc); + BtnWidth = (rc.right - rc.left); + BtnHeight = (rc.bottom - rc.top); + + // Get size of first listbox and figure height as it is same for both + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + GetWindowRect(hCtrl, &rc); + List1Width = (rc.right - rc.left); + nHeight = Height - Y_BORDER - BtnHeight - (2 * BUTTON_Y_BORDER); // subtract out borders + Splitter_Bottom = nHeight + Y_BORDER; + Splitter_Left = List1Width + X_BORDER; + + // First Listbox never changes width on Window resize + MoveWindow(hCtrl, X_BORDER, Y_BORDER, List1Width, nHeight, TRUE); + GetWindowRect(hCtrl, &rc); + nHeight = (rc.bottom - rc.top); + + // Second Listbox has width based on first and new size of Window. + if (Width > (2 * X_BORDER) + SPLITTER_WIDTH) + nWidth = Width - ( 2 * X_BORDER) - SPLITTER_WIDTH; + else + nWidth = 1; + + // Now must take off from first listbox + if (nWidth > List1Width) + nWidth -= List1Width; + else + nWidth = 1; + + hCtrl = GetDlgItem(hDlg, IDC_LIST2); + MoveWindow(hCtrl, X_BORDER + List1Width + SPLITTER_WIDTH, Y_BORDER, nWidth, nHeight, TRUE); + + // Figure out where to put the buttons + nWidth = (Width / 2) - (((3 * BtnWidth) + (2 * BUTTON_X_BORDER)) / 2); + nHeight = Height - BtnHeight - BUTTON_Y_BORDER; + hCtrl = GetDlgItem(hDlg, IDOK); + MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE); + nWidth += BtnWidth + BUTTON_X_BORDER; + + hCtrl = GetDlgItem(hDlg, IDCANCEL); + MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE); + nWidth += BtnWidth + BUTTON_X_BORDER; + + hCtrl = GetDlgItem(hDlg, IDHELP); + MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE); + +} // ControlsResize + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSelect_OnDrawItem( + HWND hwnd, + DRAWITEMSTRUCT FAR* lpDrawItem + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR szText[MAX_PATH + 1]; + DWORD dwData; + int nLevel = 0; + int nTempLevel; + int nRow = 0; + int nColumn = 0; + int chkColumn = 0; + DWORD dwConnectLevel = 0; + DWORD dwMask; + DIR_BUFFER *Dir, *Dir2; + FILE_BUFFER *File; + DIR_LIST *DirList, *DirList2; + BOOL FileBox = FALSE; + + dwData = lpDrawItem->itemData; + if (dwData == 0) + return; + + if ((lpDrawItem->CtlID != IDC_LIST1) && (lpDrawItem->CtlID != IDC_LIST2)) + return; + + if (lpDrawItem->CtlID == IDC_LIST2) + FileBox = TRUE; + + // Select the correct icon, open folder, closed folder, or document. + + if (FileBox) { + File = (FILE_BUFFER *) dwData; + lstrcpy(szText, File->Name); + nRow = 1; + chkColumn = File->Convert; + } else { + + Dir2 = Dir = (DIR_BUFFER *) dwData; + lstrcpy(szText, Dir->Name); + chkColumn = Dir->Convert; + DirList2 = DirList = (DIR_LIST *) Dir->parent; + + if (DirList != NULL) + nLevel = DirList->Level; + + // Is it open ? + if ( HierFile_IsOpened(&HierDrawStruct, dwData) ) + nColumn = 1; + else + nColumn = 0; + + // Connect level figures out what connecting lines should be drawn + // - stored as a bitmask. + if (nLevel == 0) + dwConnectLevel = 0; + else { + nTempLevel = nLevel - 1; + + // First bit to set + dwMask = (DWORD) pow(2, nLevel - 1); + + // Now go through and figure out what else to set... + while (nTempLevel >= 0) { + // Check if last child at this level... + if (!Dir2->Last) + dwConnectLevel |= dwMask; + + // figure out next parent... + Dir2 = DirList2->parent; + DirList2 = Dir2->parent; + + // move mask bit over, and up a level. + dwMask /= 2; + + // move up one level. + nTempLevel--; + } + } + } + + // All set to call drawing function. + HierFile_OnDrawItem(hwnd, lpDrawItem, nLevel, dwConnectLevel, szText, + nRow, nColumn, chkColumn, &HierDrawStruct); + + return; + +} // FileSelect_OnDrawItem + + +///////////////////////////////////////////////////////////////////////// +VOID +RecursePath( + LPTSTR Path, + DIR_BUFFER *Dir + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_LIST *DirList; + ULONG i; + + DirList = (DIR_LIST *) Dir->parent; + + if (DirList != NULL) + RecursePath(Path, (DIR_BUFFER *) DirList->parent); + + i = lstrlen(Path); + if (i) + if (Path[i-1] != TEXT('\\')) + lstrcat(Path, TEXT("\\")); + + lstrcat(Path, Dir->Name); +} // RecursePath + + +///////////////////////////////////////////////////////////////////////// +VOID +CloseList( + HWND hWndList, + DIR_BUFFER *Dir, + WORD wItemNum + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD dwIncr; + DWORD Count; + DIR_LIST *DirList; + + HierFile_CloseItem(&HierDrawStruct, (DWORD) Dir); + DirList = (DIR_LIST *) Dir->DirList; + + if (DirList != NULL) { + Count = DirList->Count; + + // Remove the child items. Close any children that are open on the way. + // wItem can stay constant - we are moveing stuff up in the listbox as we are deleting. + wItemNum++; + dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L); + + while (Count) { + // Is this child open ? + if ( HierFile_IsOpened(&HierDrawStruct, dwIncr) ) { + CloseList(hWndList, (DIR_BUFFER *) dwIncr, wItemNum); + } + + SendMessage(hWndList, LB_DELETESTRING, wItemNum, 0L); + dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L); + Count--; + } + + } + +} // CloseList + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSelect_ActionItem( + HWND hWndList, + DWORD dwData, + WORD wItemNum + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_PATH + 1]; + DWORD Count = 0; + DIR_BUFFER *Dir; + DIR_LIST *DirList; + FILE_LIST *FileList; + ULONG i; + + if (!dwData) + return; + + // Is it open ? + if ( HierFile_IsOpened(&HierDrawStruct, dwData) ) { + + // It's open ... Close it + Dir = (DIR_BUFFER *) dwData; + DirList = (DIR_LIST *) Dir->DirList; + CloseList(hWndList, Dir, wItemNum); + } else { + + // It's closed ... Open it + HierFile_OpenItem(&HierDrawStruct, dwData); + + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0L); // Disable redrawing. + + CursorHourGlass(); + + Dir = (DIR_BUFFER *) dwData; +#ifdef DEBUG +dprintf(TEXT("Opening dir: %s\r\n"), Dir->Name); +#endif + + DirList = (DIR_LIST *) Dir->parent; + if (DirList == NULL) + FillDir(1, Dir->Name, Dir, TRUE); + else { + // recurse backwards to create full path + lstrcpy(NewPath, TEXT("")); + RecursePath(NewPath, Dir); + FillDir(DirList->Level + 1, NewPath, Dir, TRUE); + } + + DirList = NULL; + + // Check if we have visited this node, if not allocate and fill it in. + if (Dir->DirList != NULL) { + DirList = (DIR_LIST *) Dir->DirList; + Count = DirList->Count; + + for (i = 0; i < DirList->Count; i++) { + SendMessage(hWndList, LB_INSERTSTRING, (WPARAM) wItemNum + i + 1, (LPARAM) &DirList->DirBuffer[i]); + } + + } + +#ifdef DEBUG +if (Dir->FileList == NULL) + dprintf(TEXT("FileList NULL\r\n")); +#endif + + if (Dir->FileList != NULL) { + FileList = (FILE_LIST *) Dir->FileList; + +#ifdef DEBUG +dprintf(TEXT("FileList Count: %li\r\n"), FileList->Count); +#endif + SendMessage(hwndList2, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0L); + for (i = 0; i < FileList->Count; i++) { + SendMessage(hwndList2, LB_ADDSTRING, (WPARAM) 0, (LPARAM) &FileList->FileBuffer[i]); + } + + } + + // Make sure as many child items as possible are showing + HierFile_ShowKids(&HierDrawStruct, hWndList, (WORD) wItemNum, (WORD) Count ); + + CursorNormal(); + } + + SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L); // Enable redrawing. + InvalidateRect(hWndList, NULL, TRUE); // Force redraw + +} // FileSelect_ActionItem + + +///////////////////////////////////////////////////////////////////////// +VOID +TreeOpenRecurse( + DIR_BUFFER *Dir, + WORD *wItemNum + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DIR_LIST *DirList = NULL; + ULONG i; + + // if it's closed, open it + if ( !HierFile_IsOpened(&HierDrawStruct, (DWORD) Dir) ) + FileSelect_ActionItem(hwndList1, (DWORD) Dir, *wItemNum); + + DirList = Dir->DirList; + if (DirList != NULL) { + + for (i = 0; i < DirList->Count; i++) { + (*wItemNum)++; + // Now recurse down the children + TreeOpenRecurse(&DirList->DirBuffer[i], wItemNum); + } + } + +} // TreeOpenRecurse + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSelect_UpdateFiles( + HWND hDlg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_PATH + 1]; + WORD wItemNum; + DWORD dwData; + HWND hCtrl; + ULONG i; + FILE_LIST *FileList; + DIR_BUFFER *Dir; + DIR_LIST *DirList; + + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + + if (wItemNum == (WORD) LB_ERR) + wItemNum = LastFocus; + + // Check first listbox and resynch the directory information so that we + // pick up the current file list. + LastFocus = wItemNum; + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if ((dwData == (DWORD) LB_ERR) || (dwData == 0)) + return; + + Dir = (DIR_BUFFER *) dwData; +#ifdef DEBUG +dprintf(TEXT("Opening dir: %lX %s\r\n"), Dir->parent, Dir->Name); +#endif + + DirList = (DIR_LIST *) Dir->parent; + if (DirList == NULL) + FillDir(1, Dir->Name, Dir, FALSE); + else { + // recurse backwards to create full path + lstrcpy(NewPath, TEXT("")); + RecursePath(NewPath, Dir); + FillDir(DirList->Level + 1, NewPath, Dir, FALSE); + } + + // Since Dir pointer was changed need to update listbox pointer + SendMessage(hCtrl, LB_SETITEMDATA, wItemNum, (LPARAM) Dir); + + // We have not re-synched the directory so we have the correct file info + // now reset the file listbox and fill it with the new file-list. + SendMessage(hwndList2, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0L); + + if (Dir->FileList != NULL) { + FileList = (FILE_LIST *) Dir->FileList; + +#ifdef DEBUG +dprintf(TEXT("FileList Count: %li\r\n"), FileList->Count); +#endif + for (i = 0; i < FileList->Count; i++) + SendMessage(hwndList2, LB_ADDSTRING, (WPARAM) 0, (LPARAM) &FileList->FileBuffer[i]); + + } + +} // FileSelect_UpdateFiles + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSelect_OnCommand( + HWND hDlg, + WPARAM wParam, + LPARAM lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NewPath[MAX_PATH + 1]; + int wmId, wmEvent; + WORD wItemNum; + DWORD dwData; + HWND hCtrl; + DIR_LIST *DirList; + FILE_LIST *FileList; + DIR_BUFFER *Dir; + int nLevel = 0; + + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + + case IDOK: + // If we are on either of the listboxes, then use the Enter key to + // activate the selected item + if (ListFocus == hwndList1) { + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + FileSelect_ActionItem(hCtrl, dwData, wItemNum); + } else { + CurrentShare->HiddenFiles = HiddenFiles; + CurrentShare->SystemFiles = SystemFiles; + + // Delete our copy of the tree and prune the tree down to minimum + // storage space + TreeDelete(oDir); + TreePrune(CurrentShare->Root); + + EndDialog(hDlg, 0); + } + + break; + + case IDCANCEL: + + // Disable listboxes since we are deleting their item data + SendDlgItemMessage(hDlg, IDC_LIST1, WM_SETREDRAW, FALSE, 0L); + SendDlgItemMessage(hDlg, IDC_LIST2, WM_SETREDRAW, FALSE, 0L); + + // Get back our old tree + if (CurrentShare->Root != NULL) + TreeDelete(CurrentShare->Root); + CurrentShare->Root = oDir; + + EndDialog(hDlg, 0); + break; + + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_FTRANS); + break; + + case IDM_EXP_ONE: + // expand the current node + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + if ( !HierFile_IsOpened(&HierDrawStruct, dwData) ) + FileSelect_ActionItem(hCtrl, dwData, wItemNum); + + break; + + case IDM_EXP_ALL: + // Open all children from the root + wItemNum = 0; + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + goto ExpandTree; + + case IDM_EXP_BRANCH: + // Traverse down the branch, opening up all children + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + +ExpandTree: + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + Dir = (DIR_BUFFER *) dwData; + CursorHourGlass(); + + TreeOpenRecurse(Dir, &wItemNum); + + CursorNormal(); + + // Force redraw + InvalidateRect(hwndList1, NULL, TRUE); + break; + + case IDM_COLLAPSE: + // Close the current branch + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + if ( HierFile_IsOpened(&HierDrawStruct, dwData) ) + FileSelect_ActionItem(hCtrl, dwData, wItemNum); + + break; + + // Not used currently + case IDM_VIEW_BOTH: + case IDM_VIEW_TREE: + case IDM_VIEW_DIR: + break; + + case IDM_HIDDEN: + HiddenFiles = !HiddenFiles; + CheckMenuItem((HMENU) wParam, IDM_HIDDEN, HiddenFiles ? MF_CHECKED : MF_UNCHECKED); + PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L); + break; + + case IDM_SYSTEM: + SystemFiles = !SystemFiles; + CheckMenuItem((HMENU) wParam, IDM_SYSTEM, SystemFiles ? MF_CHECKED : MF_UNCHECKED); + PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L); + break; + + case ID_REDRAWLIST: + FileSelect_UpdateFiles(hDlg); + break; + + case IDC_LIST1: + + switch (wmEvent) { + case LBN_SETFOCUS: + ListFocus = hwndList1; + break; + + case LBN_KILLFOCUS: + ListFocus = NULL; + break; + + case LBN_DBLCLK: + // Disregard the DBLCLK message if it is inside a checkbox. + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + + // First figure out where checkbox is located in listbox + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + Dir = (DIR_BUFFER *) dwData; + DirList = (DIR_LIST *) Dir->parent; + + if (DirList != NULL) + nLevel = DirList->Level; + + if (!HierFile_InCheck(nLevel, LOWORD(mouseHit), &HierDrawStruct)) { + CursorHourGlass(); + FileSelect_ActionItem(hCtrl, dwData, wItemNum); + CursorNormal(); + } + + break; + + case LBN_SELCHANGE: + FileSelect_UpdateFiles(hDlg); + break; + + } + + break; + + case ID_UPDATELIST: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + if (CurrentShare->Root == NULL) { + wsprintf(NewPath, TEXT("\\\\%s\\%s\\"), SServ->Name, CurrentShare->Name); + +#ifdef DEBUG +// lstrcpy(NewPath, TEXT("c:\\")); +dprintf(TEXT("Root Path: %s\n"), NewPath); +#endif + TreeRootInit(CurrentShare, NewPath); + } + + PostMessage(hCtrl, LB_SETCURSEL, (WPARAM) 0, 0L); + LastFocus = 0; + + DirList = (DIR_LIST *) CurrentShare->Root->DirList; + FileList = (FILE_LIST *) CurrentShare->Root->FileList; + + wItemNum = (WORD) SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) CurrentShare->Root); + PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + } + +} // FileSelect_OnCommand + + +///////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK +FileSelectSubClassProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam + ) + +/*++ + +Routine Description: + + Handles key processing for the hierarchical listbox. Specifically + the up/down arrow keys and the letter keys. + +Arguments: + + +Return Value: + + +--*/ + +{ + LRESULT lResult = 0; + BOOL fCallOrigProc = TRUE; + WORD wItemNum, wNewNum; + DWORD dwData; + DIR_BUFFER *Dir; + DIR_LIST *DirList; + FILE_BUFFER *File; + int nLevel = 0; + int lHeight, ListHeight, PageCount; + + RECT rc; + + switch (message) { + case WM_LBUTTONDOWN: + // Send message to check if button-down is within our checkbox + wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + + // Save the location off so we can check it during a DBLCLK message + // to see if we are inside a checkbox. + mouseHit = lParam; + + // Post the message so the current selection is correct + PostMessage(hWnd, WM_COMMAND, ID_CHECKCHECK, lParam); + break; + + case WM_COMMAND: + // Code for handling checkbox clicking + if (wParam == ID_CHECKCHECK) { + // First figure out where checkbox is located in listbox + wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + + if (wItemNum == (WORD) LB_ERR) + break; + + if (hWnd == hwndList2) { + File = (FILE_BUFFER *) dwData; + + if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) { + if (File->Convert == CONVERT_NONE) + File->Convert = CONVERT_ALL; + else + File->Convert = CONVERT_NONE; + + DirAdjustConvert(File->parent->parent); + } + + } else { + Dir = (DIR_BUFFER *) dwData; + DirList = (DIR_LIST *) Dir->parent; + + if (DirList != NULL) + nLevel = DirList->Level; + + if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) { + if (Dir->Convert == CONVERT_NONE) + DirAdjustConvertChildren(Dir, CONVERT_ALL); + else + DirAdjustConvertChildren(Dir, CONVERT_NONE); + + DirAdjustConvert(Dir); + } + } + + // Now check if button click was within checkbox boundaries... + if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) { + + // We have set the checkbox state correctly on the current item, + // and propageted this up and down the tree as necessary, now + // update the screen to reflect these changes. + InvalidateRect(hWnd, NULL, TRUE); // Force redraw + + // if this is the directory listbox then also need to redraw + // the file listbox + if (hWnd == hwndList1) + InvalidateRect(hwndList2, NULL, TRUE); + + } + } + + break; + + case WM_KEYDOWN: + wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + if (wItemNum != (WORD) LB_ERR) + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + else { + wItemNum = 0; + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + } + + if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0)) + break; + + fCallOrigProc = FALSE; + + switch (LOWORD(wParam)) { + + case VK_PRIOR: + // Need to figure out the number of items to page. This + // would be the listbox height divided by the height of + // a listbox item + lHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0L); + GetWindowRect(hWnd, &rc); + ListHeight = (rc.bottom - rc.top); + + if (ListHeight) + PageCount = ListHeight / lHeight; + else + PageCount = 0; + + // See if we page past the top - if so adjust it. + if (wItemNum > PageCount) + wNewNum = wItemNum - PageCount; + else + wNewNum = 0; + + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wNewNum, 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + case VK_NEXT: + // Need to figure out the number of items to page. This + // would be the listbox height divided by the height of + // a listbox item + lHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0L); + GetWindowRect(hWnd, &rc); + ListHeight = (rc.bottom - rc.top); + + if (ListHeight) + PageCount = ListHeight / lHeight; + else + PageCount = 0; + + // Figure out if we page past the end - if so adjust it + wItemNum = wItemNum + PageCount; + wNewNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L); + + if (wItemNum < wNewNum) + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + else + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wNewNum - 1), 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + case VK_END: + wItemNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L); + + if (wItemNum != (WORD) LB_ERR) + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wItemNum - 1), 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + case VK_HOME: + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) 0, 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + case VK_UP: + if (wItemNum > 0) { + wItemNum--; + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + } + break; + + case VK_DOWN: + wItemNum++; + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + + if (hWnd == hwndList1) + PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L); + + break; + + case VK_F1: + fCallOrigProc = TRUE; + break; + + case VK_SPACE: + // First figure out where checkbox is located in listbox + wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + + if (wItemNum == (WORD) LB_ERR) + break; + + if (hWnd == hwndList2) { + File = (FILE_BUFFER *) dwData; + + if (File->Convert == CONVERT_NONE) + File->Convert = CONVERT_ALL; + else + File->Convert = CONVERT_NONE; + + DirAdjustConvert(File->parent->parent); + } else { + Dir = (DIR_BUFFER *) dwData; + DirList = (DIR_LIST *) Dir->parent; + + if (DirList != NULL) + nLevel = DirList->Level; + + if (Dir->Convert == CONVERT_NONE) + DirAdjustConvertChildren(Dir, CONVERT_ALL); + else + DirAdjustConvertChildren(Dir, CONVERT_NONE); + + DirAdjustConvert(Dir); + } + + // We have set the checkbox state correctly on the current item, + // and propageted this up and down the tree as necessary, now + // update the screen to reflect these changes. + InvalidateRect(hWnd, NULL, TRUE); // Force redraw + + // if this is the directory listbox then also need to redraw + // the file listbox + if (hWnd == hwndList1) + InvalidateRect(hwndList2, NULL, TRUE); + + break; + + default: + break; + + } + + break; + + } + + if (fCallOrigProc) + if (hWnd == hwndList2) + lResult = CallWindowProc(_wpOrigWndProc2, hWnd, message, wParam, lParam); + else + lResult = CallWindowProc(_wpOrigWndProc, hWnd, message, wParam, lParam); + + return (lResult); + +} // FileSelectSubClassProc + + +///////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK +DlgFileSelect( + HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + int xPos; + int yPos; + BOOL InRange; + RECT rc; + HWND hCtrl; + + switch (message) { + case WM_INITDIALOG: + // Copy the tree + oDir = CurrentShare->Root; + CurrentShare->Root = TreeCopy(oDir); + + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + GetClientRect(hDlg, &rc); + ControlsResize(hDlg, (rc.bottom - rc.top), (rc.right - rc.left)); + + // subclass listbox handler + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + _wpOrigWndProc = SubclassWindow(hCtrl, FileSelectSubClassProc); + hCtrl = GetDlgItem(hDlg, IDC_LIST2); + _wpOrigWndProc2 = SubclassWindow(hCtrl, FileSelectSubClassProc); + + FillDirInit(); + + hwndList2 = hCtrl = GetDlgItem(hDlg, IDC_LIST2); + hwndList1 = GetDlgItem(hDlg, IDC_LIST1); + + // Fill listbox and set selection (is assumed there is always a selection)... + PostMessage(hDlg, WM_COMMAND, ID_UPDATELIST, 0L); + return (TRUE); + + case WM_INITMENU: + if (GetMenu(hDlg) != (HMENU) wParam) + break; + + CheckMenuItem((HMENU) wParam, IDM_HIDDEN, HiddenFiles ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem((HMENU) wParam, IDM_SYSTEM, SystemFiles ? MF_CHECKED : MF_UNCHECKED); + break; + + case WM_SIZE: + ControlsResize(hDlg, HIWORD(lParam), LOWORD(lParam)); + break; + + case WM_SETFONT: + // Set the text height + HierFile_DrawSetTextHeight(GetDlgItem(hDlg, IDC_LIST1), (HFONT)wParam, &HierDrawStruct); + break; + + case WM_DRAWITEM: + FileSelect_OnDrawItem(hDlg, (DRAWITEMSTRUCT FAR*)(lParam)); + return TRUE; + + case WM_MEASUREITEM: + HierFile_OnMeasureItem(hDlg, (MEASUREITEMSTRUCT FAR*)(lParam), &HierDrawStruct); + return TRUE; + + case WM_MOUSEMOVE: { + xPos = LOWORD(lParam); + yPos = HIWORD(lParam); + + InRange = TRUE; + + // Check if it is correct Y-coordinate + if ((yPos <= Y_BORDER) || (yPos >= Splitter_Bottom)) + InRange = FALSE; + + // Now Check X-coordinate + if ((xPos < Splitter_Left) || (xPos > (Splitter_Left + X_BORDER))) + InRange = FALSE; + + // Is within range of splitter, so handle it... + } + break; + + case WM_COMMAND: + FileSelect_OnCommand(hDlg, wParam, lParam); + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgFileSelect + + +///////////////////////////////////////////////////////////////////////// +VOID +FileSelect_Do( + HWND hDlg, + SOURCE_SERVER_BUFFER *SourceServ, + SHARE_BUFFER *CShare + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DLGPROC lpfnDlg; + + TreeRecurseCurrentShareSet(CShare); + SServ = SourceServ; + + HiddenFiles = CurrentShare->HiddenFiles; + SystemFiles = CurrentShare->SystemFiles; + + // Init the Hier Draw stuff - Need to do this here so we have a value + // for WM_MEASUREITEM which is sent before the WM_INITDIALOG message + HierFile_DrawInit(hInst, IDR_FILEICONS, IDR_CHECKICONS, ROWS, COLS, TRUE, &HierDrawStruct, TRUE ); + + lpfnDlg = MakeProcInstance((DLGPROC)DlgFileSelect, hInst); + DialogBox(hInst, TEXT("FileSelect"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + + HierFile_DrawTerm(&HierDrawStruct); + +} // FileSelect_Do diff --git a/private/nw/convert/nwconv/filesel.h b/private/nw/convert/nwconv/filesel.h new file mode 100644 index 000000000..f09ac1676 --- /dev/null +++ b/private/nw/convert/nwconv/filesel.h @@ -0,0 +1,130 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HFILESEL_ +#define _HFILESEL_ + +#ifdef __cplusplus +extern "C"{ +#endif + +// Forward references as the structures are recursively linked +struct _DIR_BUFFER; +struct _DIR_LIST; +struct _FILE_BUFFER; +struct _FILE_LIST; +struct SHARE_BUFFER; + +/*+-------------------------------------------------------------------------+ + | + | The dir/file lists contain all the information used when working with + | a file tree. The naming convention is that a buffer (I.E. + | DIR_BUFFER) contains the information for one entry (one directory + | or one file). A List is an array of buffers of the appropriate + | type (DIR_LIST contains an array of DIR_BUFFERS). + | + | The whole mess starts with a root DIR_BUFFER, the DIR_BUFFER then + | points to a cascading chain of DIR and FILE LISTS. + | + | Almost all of the structures are a doubly linked list with a pointer back + | to their parent. A buffer parent pointer, points to it's parent list + | structure. The List structure then has a back pointer to the parent + | DIR_BUFFER. This facilitates recursing up and down the chain when + | an item is checked/un-checked and it's parent and/or children are affected. + | + | +--------+ +----------+ + | | Dir |<--->| Dir List | + | | Buffer |<-+ +----------+ + | +--------+ | | Dir |-->Dir List... + | | | Buffer |-->File List... + | | + - - - - -+ + | | | | + | | + - - - - -+ + | | | | + | | + | | + | | +-----------+ + | +->| File List | + | +-----------+ + | | File | + | | Buffer | + | + - - - - - + + | | | + | + - - - - - + + | | | + | + +-------------------------------------------------------------------------+*/ +#define CONVERT_NONE 0 +#define CONVERT_ALL 1 +#define CONVERT_PARTIAL 2 + +// A dir buffer holds a directory or sub-directory entry, with pointers to the +// files and other dirs within it. +typedef struct _DIR_BUFFER { + TCHAR Name[MAX_PATH]; + struct _DIR_LIST *parent; + BOOL Last; // Flag is last dir-buffer in list + DWORD Attributes; + BYTE Convert; // None, All or Partial + BOOL Special; + + struct _DIR_LIST *DirList; // Directory List structure + struct _FILE_LIST *FileList; // File List structure +} DIR_BUFFER; + +// A dir list contains the sub-directories in a directory - basically a count +// and then array of sub-dirs. +typedef struct _DIR_LIST { + ULONG Count; + DIR_BUFFER *parent; + UINT Level; // how deeply nested in file tree (nesting level) + DIR_BUFFER DirBuffer[]; +} DIR_LIST; + + +// Structures to hold information on individual files selected/de-selected for +// conversion +typedef struct _FILE_BUFFER { + TCHAR Name[MAX_PATH]; + struct _FILE_LIST *parent; + BOOL Convert; + DWORD Attributes; + ULONG Size; +} FILE_BUFFER; + +typedef struct _FILE_LIST { + ULONG Count; + DIR_BUFFER *parent; + FILE_BUFFER FileBuffer[]; +} FILE_LIST; + + +typedef struct _FILE_PATH_BUFFER { + LPTSTR Server; + LPTSTR Share; + LPTSTR Path; + TCHAR FullPath[MAX_PATH + 1]; +} FILE_PATH_BUFFER; + + +/*+-------------------------------------------------------------------------+ + | Function Prototypes | + +-------------------------------------------------------------------------+*/ +void TreeDelete(DIR_BUFFER *Dir); +void TreePrune(DIR_BUFFER *Dir); +ULONG TreeCount(DIR_BUFFER *Dir); +DIR_BUFFER *TreeCopy(DIR_BUFFER *Dir); + +FILE_PATH_BUFFER *FilePathInit(); +void FilePathServerSet(FILE_PATH_BUFFER *fpBuf, LPTSTR Server); +void FilePathShareSet(FILE_PATH_BUFFER *fpBuf, LPTSTR Share); +void FilePathPathSet(FILE_PATH_BUFFER *fpBuf, LPTSTR Path); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/private/nw/convert/nwconv/fpnwapi.h b/private/nw/convert/nwconv/fpnwapi.h new file mode 100644 index 000000000..a5d7b372d --- /dev/null +++ b/private/nw/convert/nwconv/fpnwapi.h @@ -0,0 +1,76 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +// Munged needed defines from FPNW code - fpnwapi.h file + +#ifndef _FPNWAPI_H_ +#define _FPNWAPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// +// Volume types : disk or printer +// + +#define NWVOL_TYPE_DISKTREE FPNWVOL_TYPE_DISKTREE +#define NWVOL_TYPE_CDROM FPNWVOL_TYPE_CDROM +#define NWVOL_TYPE_REMOVABLE FPNWVOL_TYPE_REMOVABLE + +#define NWVOL_MAX_USES_UNLIMITED ((ULONG)-1) + +// +// Volume flags returned by VolumeGetInfo +// + +#define FPNWVOL_TYPE_DISKTREE 0 +#define FPNWVOL_TYPE_CDROM 104 +#define FPNWVOL_TYPE_REMOVABLE 105 + +// +// Permissions flags returned in structure FPNWFILEINFO +// + +#define FPNWFILE_PERM_NONE 0 +#define FPNWFILE_PERM_READ 0x01 +#define FPNWFILE_PERM_WRITE 0x02 +#define FPNWFILE_PERM_CREATE 0x04 +#define FPNWFILE_PERM_EXEC 0x08 +#define FPNWFILE_PERM_DELETE 0x10 +#define FPNWFILE_PERM_ATRIB 0x20 +#define FPNWFILE_PERM_PERM 0x40 + +typedef BYTE FPNWSERVERADDR[12]; // Network address, first 4 bytes is + // the network number, and bytes + // 5-10 is the physical node + // address. The last two bytes are + // reserved. + +// +// This is the level 1 structure for FpnwVolumeAdd, FpnwVolumeDel, FpnwVolumeEnum, +// FpnwVolumeGetInfo, & FpnwVolumeSetInfo. +// + +typedef struct _FPNWVolumeInfo +{ + LPWSTR lpVolumeName; // Name of the volume + DWORD dwType; // The type of the volume. It can be one of the + // following: FPNWVOL_TYPE_DISK, FPNWVOL_TYPE_PRINT + DWORD dwMaxUses; // Maximum number of connections that are + // allowed to the volume + DWORD dwCurrentUses; // Current number of connections to the volume + LPWSTR lpPath; // Path of the volume + +} FPNWVOLUMEINFO, *PFPNWVOLUMEINFO; + +typedef FPNWVOLUMEINFO NWVOLUMEINFO, *PNWVOLUMEINFO; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/private/nw/convert/nwconv/globals.h b/private/nw/convert/nwconv/globals.h new file mode 100644 index 000000000..d641ed67c --- /dev/null +++ b/private/nw/convert/nwconv/globals.h @@ -0,0 +1,48 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HGLOBALS_ +#define _HGLOBALS_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "switches.h" +#include "constant.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" +#include "debug.h" +#include "nwlog.h" +#include "tab.h" +#include "mem.h" +#include "error.h" +#include "strings.h" +#include "utils.h" + +extern HINSTANCE hInst; + +#define XCHG(x) MAKEWORD( HIBYTE(x), LOBYTE(x) ) +#define DXCHG(x) MAKELONG( XCHG(HIWORD(x)), XCHG(LOWORD(x)) ) +#define SWAPBYTES(w) ((w) = XCHG(w)) +#define SWAPWORDS(d) ((d) = DXCHG(d)) + +#define HELP_FILE TEXT("NWConv.HLP") + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/helpid.h b/private/nw/convert/nwconv/helpid.h new file mode 100644 index 000000000..9ade43cc9 --- /dev/null +++ b/private/nw/convert/nwconv/helpid.h @@ -0,0 +1,70 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HHELPID_ +#define _HHELPID_ + +#ifdef __cplusplus +extern "C"{ +#endif + +// Identifiers for help contexts + +// Main dialog box +#define IDM_HELP_OPEN 500 +#define IDM_HELP_INDEX 501 +#define IDM_HELP_USING 502 +#define IDC_HELP_MAIN 503 + +#define IDM_HELP_RCONFIG 504 +#define IDM_HELP_SCONFIG 505 +#define IDM_HELP_RDCONFIG 506 +#define IDM_HELP_EXIT 507 + +#define IDM_HELP_HELPABOUT 508 + +// Select Servers for Conversion & Server Browse +#define IDC_HELP_ADD 520 +#define IDC_HELP_BROWSENW 521 +#define IDC_HELP_BROWSENT 522 + +// Logging dialog box +#define IDC_HELP_LOGGING 530 + +// User Options +#define IDC_HELP_USER 540 +#define IDC_HELP_USERADV 541 +#define IDC_HELP_TRUSTED 542 + +// File Options +#define IDC_HELP_FILE 550 + +// Add/Modify Share +#define IDC_HELP_SHAREADD 560 +#define IDC_HELP_SHAREMOD 561 +#define IDC_HELP_SHARENEW 562 +#define IDC_HELP_SHAREPROP 563 + +// Files to Transfer +#define IDC_HELP_FTRANS 570 +#define IDM_HELP_EXPL 571 +#define IDM_HELP_EXPB 572 +#define IDM_HELP_EXPA 573 +#define IDM_HELP_COLLAPSE 574 +#define IDM_HELP_VTDIR 575 +#define IDM_HELP_VTREE 576 +#define IDM_HELP_VDIR 577 +#define IDM_HELP_SPLIT 578 +#define IDM_HELP_THIDDEN 579 +#define IDM_HELP_TSYSTEM 580 +#define IDM_HELP_TKEEP 581 + +// Mapping Create +#define IDC_HELP_CMAP 590 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/hierchk.bmp b/private/nw/convert/nwconv/hierchk.bmp new file mode 100644 index 000000000..27af032f3 Binary files /dev/null and b/private/nw/convert/nwconv/hierchk.bmp differ diff --git a/private/nw/convert/nwconv/hierdraw.c b/private/nw/convert/nwconv/hierdraw.c new file mode 100644 index 000000000..7fe150924 --- /dev/null +++ b/private/nw/convert/nwconv/hierdraw.c @@ -0,0 +1,403 @@ +#include +#include +#include +#include + +#include "hierdraw.h" + + +VOID HierDraw_DrawTerm(LPHEIRDRAWSTRUCT lpHierDrawStruct) { + if (lpHierDrawStruct->hbmIcons) { + if (lpHierDrawStruct->hbmMem) + SelectObject(lpHierDrawStruct->hdcMem,lpHierDrawStruct->hbmMem); + lpHierDrawStruct->hbmMem = NULL; + DeleteObject(lpHierDrawStruct->hbmIcons); + lpHierDrawStruct->hbmIcons = NULL; + } + + if ( lpHierDrawStruct->hdcMem ) { + DeleteDC(lpHierDrawStruct->hdcMem); + lpHierDrawStruct->hdcMem = NULL; + } +} // HierDraw_DrawTerm + +VOID HierDraw_DrawCloseAll(LPHEIRDRAWSTRUCT lpHierDrawStruct ) { + lpHierDrawStruct->NumOpened= 0; + if ( lpHierDrawStruct->Opened ) { + _ffree(lpHierDrawStruct->Opened); + } + lpHierDrawStruct->Opened = NULL; +} // HierDraw_DrawCloseAll + +VOID HierDraw_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT FAR* lpMeasureItem, + LPHEIRDRAWSTRUCT lpHierDrawStruct) { + lpMeasureItem->itemHeight = max(lpHierDrawStruct->nBitmapHeight, + lpHierDrawStruct->nTextHeight); +} // HierDraw_OnMeasureItem + +VOID HierDraw_DrawSetTextHeight (HWND hwndList, HFONT hFont, LPHEIRDRAWSTRUCT lpHierDrawStruct ) { + TEXTMETRIC TextMetrics; + HANDLE hOldFont=NULL; + HDC hdc; + + // + // This sure looks like a lot of work to find the character height + // + hdc = GetDC(hwndList); + + hOldFont = SelectObject(hdc, hFont); + GetTextMetrics(hdc, &TextMetrics); + SelectObject(hdc, hOldFont); + ReleaseDC(hwndList, hdc); + + lpHierDrawStruct->nTextHeight = TextMetrics.tmHeight; + + lpHierDrawStruct->nLineHeight = + max(lpHierDrawStruct->nBitmapHeight, lpHierDrawStruct->nTextHeight); + + if ( hwndList != NULL ) + SendMessage(hwndList, LB_SETITEMHEIGHT, 0, + MAKELPARAM(lpHierDrawStruct->nLineHeight, 0)); +} // HierDraw_DrawSetTextHeight + +static DWORD near RGB2BGR(DWORD rgb) { + return RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb)); +} // RGB2BGR + +/* + * Creates the objects used while drawing the tree. This may be called + * repeatedly in the event of a WM_SYSCOLORCHANGED message. + * + * WARNING: the Tree icons bitmap is assumed to be a 16 color DIB! + */ + +BOOL HierDraw_DrawInit(HINSTANCE hInstance, + int nBitmap, + int nRows, + int nColumns, + BOOL bLines, + LPHEIRDRAWSTRUCT lpHierDrawStruct, + BOOL bInit) { + HANDLE hRes; + HANDLE hResMem; + LPBITMAPINFOHEADER lpbiReadOnly; + LPBITMAPINFOHEADER lpbiReadWrite; + DWORD *lpColorTable; + LPSTR lpBits; + int biSize; + int bc; + HDC hDC; + + if ( bInit ) { + lpHierDrawStruct->NumOpened = 0; + lpHierDrawStruct->Opened = NULL; + lpHierDrawStruct->bLines = bLines; + } + + // + // If the Memory DC is not created yet do that first. + // + if (!lpHierDrawStruct->hdcMem) { + // + // get a screen DC + // + hDC = GetDC(NULL); + // + // Create a memory DC compatible with the screen + // + lpHierDrawStruct->hdcMem = CreateCompatibleDC(hDC); + // + // Release the Screen DC + ReleaseDC(NULL,hDC); + + if (!lpHierDrawStruct->hdcMem) + return FALSE; + + lpHierDrawStruct->hbmMem = NULL; + } + + // + // (Re)Load the Bitmap ( original from disk ) + // + // Use the FindResource,LoadResource,LockResource since it makes + // it easy to get the pointer to the BITMAPINFOHEADER we need. + // + // + hRes = FindResource(hInstance, MAKEINTRESOURCE(nBitmap), RT_BITMAP); + if (!hRes) + return FALSE; + + hResMem = LoadResource(hInstance, hRes); + if (!hResMem) + return FALSE; + + // Now figure out the bitmaps background color. + // This code assumes the lower left corner is a + // bit in the background color. + lpbiReadOnly = (LPBITMAPINFOHEADER)LockResource(hResMem); + if (!lpbiReadOnly) + return FALSE; + + // Determine size of bitmap information header plus color table entries + biSize = lpbiReadOnly->biSize + ((1 << (lpbiReadOnly->biBitCount)) * sizeof(RGBQUAD)); + + // Allocate copy of the bitmap information to munge on + lpbiReadWrite = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR, biSize); + if (!lpbiReadWrite) + return FALSE; + + memcpy(lpbiReadWrite, lpbiReadOnly, biSize); + + // Color table immediately follows bitmap information header + lpColorTable = (DWORD FAR *)((LPBYTE)lpbiReadWrite + lpbiReadWrite->biSize); + + // No need to munge bits so use original + lpBits = (LPBYTE)lpbiReadOnly + biSize; + + bc = (lpBits[0] & 0xF0) >> 4; // ASSUMES LOWER LEFT CORNER IS BG!! + + lpColorTable[bc] = RGB2BGR(GetSysColor(COLOR_WINDOW)); + + hDC = GetDC(NULL); + + lpHierDrawStruct->hbmIcons = CreateDIBitmap( + hDC, + lpbiReadWrite, + CBM_INIT, + lpBits, + (LPBITMAPINFO)lpbiReadWrite, + DIB_RGB_COLORS + ); + + ReleaseDC(NULL,hDC); + + lpHierDrawStruct->nBitmapHeight = (WORD)lpbiReadWrite->biHeight / nRows; + lpHierDrawStruct->nBitmapWidth = (WORD)lpbiReadWrite->biWidth / nColumns; + + lpHierDrawStruct->nLineHeight = + max(lpHierDrawStruct->nBitmapHeight, lpHierDrawStruct->nTextHeight); + + GlobalFree(lpbiReadWrite); + UnlockResource(hResMem); + FreeResource(hResMem); + + if (!lpHierDrawStruct->hbmIcons) + return FALSE; + + lpHierDrawStruct->hbmMem = SelectObject(lpHierDrawStruct->hdcMem,lpHierDrawStruct->hbmIcons); + if (!lpHierDrawStruct->hbmMem) + return FALSE; + + return TRUE; +} // HierDraw_DrawInit + + + +VOID HierDraw_OnDrawItem(HWND hwnd, + const DRAWITEMSTRUCT FAR* lpDrawItem, + int nLevel, + DWORD dwConnectLevel, + TCHAR *szText, + int nRow, + int nColumn, + LPHEIRDRAWSTRUCT lpHierDrawStruct) { + HDC hDC; + WORD wIndent, wTopBitmap, wTopText; + RECT rcTemp; + + + if ( lpDrawItem->itemID == (UINT)-1 ) + return ; + + hDC = lpDrawItem->hDC; + CopyRect(&rcTemp, &lpDrawItem->rcItem); + + wIndent = rcTemp.left + ((int)(nLevel) * lpHierDrawStruct->nBitmapWidth) + XBMPOFFSET; + rcTemp.left = wIndent + lpHierDrawStruct->nBitmapWidth; + wTopText = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierDrawStruct->nTextHeight / 2); + wTopBitmap = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierDrawStruct->nBitmapHeight / 2); + + if (lpDrawItem->itemAction == ODA_FOCUS) + goto DealWithFocus; + else if (lpDrawItem->itemAction == ODA_SELECT) + goto DealWithSelection; + + // + // Draw some lions, if we like lions + // + + if (lpHierDrawStruct->bLines && nLevel) + { + DWORD dwMask = 1; + int nTempLevel; + int x,y; + + // draw lines in text color + SetBkColor(hDC,GetSysColor(COLOR_WINDOWTEXT)); + + // + // Draw a series of | lines for outer levels + // + + x = lpHierDrawStruct->nBitmapWidth/2 + XBMPOFFSET; + + for ( nTempLevel = 0; nTempLevel < nLevel ; nTempLevel++) + { + if ( dwConnectLevel & dwMask ) + FastRect(hDC,x,rcTemp.top,1,rcTemp.bottom - rcTemp.top); + + x += lpHierDrawStruct->nBitmapWidth; + dwMask *= 2; + } + + + // + // Draw the short vert line up towards the parent + // + nTempLevel = nLevel-1; + dwMask *= 2; + + x = nTempLevel * lpHierDrawStruct->nBitmapWidth + lpHierDrawStruct->nBitmapWidth / 2 + XBMPOFFSET; + + if ( dwConnectLevel & dwMask ) + y = rcTemp.bottom; + else + y = rcTemp.bottom - lpHierDrawStruct->nLineHeight / 2; + + FastRect(hDC,x,rcTemp.top,1,y-rcTemp.top); + + // + // Draw short horiz bar to right + // + FastRect(hDC,x,rcTemp.bottom-lpHierDrawStruct->nLineHeight/2,lpHierDrawStruct->nBitmapWidth/2,1); + } + + // + // Draw the selected bitmap + // + + BitBlt(hDC, + wIndent,wTopBitmap, + lpHierDrawStruct->nBitmapWidth,lpHierDrawStruct->nBitmapHeight, + lpHierDrawStruct->hdcMem, + nColumn*lpHierDrawStruct->nBitmapWidth, + nRow*lpHierDrawStruct->nBitmapHeight, + SRCCOPY); + +DealWithSelection: + + if (lpDrawItem->itemState & ODS_SELECTED) + { + SetBkColor(hDC,GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(hDC,GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + else + { + SetBkColor(hDC,GetSysColor(COLOR_WINDOW)); + SetTextColor(hDC,GetSysColor(COLOR_WINDOWTEXT)); + } + + + ExtTextOut(hDC, rcTemp.left + 1, wTopText, ETO_CLIPPED|ETO_OPAQUE, + &rcTemp,szText,lstrlen(szText), NULL); + + if (lpDrawItem->itemState & ODS_FOCUS && lpDrawItem->itemAction != ODA_SELECT) { +DealWithFocus: + DrawFocusRect(hDC, &rcTemp); + } + + +} // HierDraw_OnDrawItem + + +// +// draw a solid color rectangle quickly +// +static VOID near FastRect(HDC hDC, int x, int y, int cx, int cy) { + RECT rc; + + rc.left = x; + rc.right = x+cx; + rc.top = y; + rc.bottom = y+cy; + ExtTextOut(hDC,x,y,ETO_OPAQUE,&rc,NULL,0,NULL); +} // FastRect + + +BOOL HierDraw_IsOpened(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) { + // For Now just a dumb search + // + int Count; + + for ( Count = 0; Count < lpHierDrawStruct->NumOpened; Count++ ) { + if ( lpHierDrawStruct->Opened[Count] == dwData ) { + return TRUE; + } + } + + return FALSE; + +} // HierDraw_IsOpened + + +VOID HierDraw_OpenItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) { + lpHierDrawStruct->NumOpened++; + + if (lpHierDrawStruct->Opened == NULL ) + lpHierDrawStruct->Opened = + (DWORD FAR *)_fmalloc(sizeof(DWORD)*lpHierDrawStruct->NumOpened); + else + lpHierDrawStruct->Opened = + (DWORD FAR *)_frealloc(lpHierDrawStruct->Opened, + sizeof(DWORD)*lpHierDrawStruct->NumOpened); + + lpHierDrawStruct->Opened[lpHierDrawStruct->NumOpened-1] = dwData; +} // HierDraw_OpenItem + + +VOID HierDraw_CloseItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) { + // For Now just a dumb search + // + int Count; + + for ( Count = 0; Count < lpHierDrawStruct->NumOpened; Count++ ) { + if ( lpHierDrawStruct->Opened[Count] == dwData ) { + if (--lpHierDrawStruct->NumOpened == 0 ) { + _ffree(lpHierDrawStruct->Opened); + lpHierDrawStruct->Opened = NULL; + } + else { + if ( Count < lpHierDrawStruct->NumOpened ) { + _fmemmove(&(lpHierDrawStruct->Opened[Count]), + &(lpHierDrawStruct->Opened[Count+1]), + sizeof(DWORD)*(lpHierDrawStruct->NumOpened-Count)); + } + lpHierDrawStruct->Opened = + (DWORD FAR *)_frealloc(lpHierDrawStruct->Opened, + sizeof(DWORD)*lpHierDrawStruct->NumOpened); + } + } + } +} // HierDraw_CloseItem + + +VOID HierDraw_ShowKids(LPHEIRDRAWSTRUCT lpHierDrawStruct, + HWND hwndList, WORD wCurrentSelection, WORD wKids) { + WORD wBottomIndex; + WORD wTopIndex; + WORD wNewTopIndex; + WORD wExpandInView; + RECT rc; + + wTopIndex = (WORD)SendMessage(hwndList, LB_GETTOPINDEX, 0, 0L); + GetClientRect(hwndList, &rc); + wBottomIndex = wTopIndex + (rc.bottom+1) / lpHierDrawStruct->nLineHeight; + + wExpandInView = (wBottomIndex - wCurrentSelection); + + if (wKids >= wExpandInView) { + wNewTopIndex = min(wCurrentSelection, wTopIndex + wKids - wExpandInView + 1); + SendMessage(hwndList, LB_SETTOPINDEX, (WORD)wNewTopIndex, 0L); + } + +} // HierDraw_ShowKids diff --git a/private/nw/convert/nwconv/hierdraw.h b/private/nw/convert/nwconv/hierdraw.h new file mode 100644 index 000000000..f8007fbee --- /dev/null +++ b/private/nw/convert/nwconv/hierdraw.h @@ -0,0 +1,65 @@ +#define XBMPOFFSET 2 + + +typedef struct _HierDrawStruct { + HDC hdcMem; + HBITMAP hbmIcons; + HBITMAP hbmMem; + int nBitmapHeight; + int nBitmapWidth; + int nTextHeight; + int nLineHeight; + BOOL bLines; + int NumOpened; + DWORD FAR *Opened; + +} HEIRDRAWSTRUCT; + +typedef HEIRDRAWSTRUCT FAR * LPHEIRDRAWSTRUCT ; + + +// +// Interface functions +// +VOID HierDraw_DrawTerm(LPHEIRDRAWSTRUCT lpHierDrawStruct); + +VOID HierDraw_DrawSetTextHeight (HWND hwnd, HFONT hFont, LPHEIRDRAWSTRUCT lpHierDrawStruct ); + +BOOL HierDraw_DrawInit(HINSTANCE hInstance, + int nBitmap, + int nRows, + int nColumns, + BOOL bLines, + LPHEIRDRAWSTRUCT lpHierDrawStruct, + BOOL bInit); + + +VOID HierDraw_OnDrawItem(HWND hwnd, + const DRAWITEMSTRUCT FAR* lpDrawItem, + int nLevel, + DWORD dwConnectLevel, + TCHAR *szText, + int nRow, + int nColumn, + LPHEIRDRAWSTRUCT lpHierDrawStruct); + + +VOID HierDraw_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT FAR* lpMeasureItem, + LPHEIRDRAWSTRUCT lpHierDrawStruct); + +BOOL HierDraw_IsOpened(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData); + +VOID HierDraw_OpenItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData); + +VOID HierDraw_CloseItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData); + +VOID HierDraw_DrawCloseAll(LPHEIRDRAWSTRUCT lpHierDrawStruct ); + +VOID HierDraw_ShowKids(LPHEIRDRAWSTRUCT lpHierDrawStruct, + HWND hwndList, WORD wCurrentSelection, WORD wKids); + +// +// Support functions +// +static VOID near FastRect(HDC hDC, int x, int y, int cx, int cy); +static DWORD near RGB2BGR(DWORD rgb); diff --git a/private/nw/convert/nwconv/hierfile.c b/private/nw/convert/nwconv/hierfile.c new file mode 100644 index 000000000..edb8481dd --- /dev/null +++ b/private/nw/convert/nwconv/hierfile.c @@ -0,0 +1,506 @@ +#include +#include +#include +#include + +#include "debug.h" +#include "HierFile.h" + + +VOID HierFile_DrawTerm(LPHEIRDRAWSTRUCT lpHierFileStruct) { + if (lpHierFileStruct->hbmIcons1) { + if (lpHierFileStruct->hbmMem1) + SelectObject(lpHierFileStruct->hdcMem1, lpHierFileStruct->hbmMem1); + lpHierFileStruct->hbmMem1 = NULL; + DeleteObject(lpHierFileStruct->hbmIcons1); + lpHierFileStruct->hbmIcons1 = NULL; + } + + if ( lpHierFileStruct->hdcMem1 ) { + DeleteDC(lpHierFileStruct->hdcMem1); + lpHierFileStruct->hdcMem1 = NULL; + } + + if (lpHierFileStruct->hbmIcons2) { + if (lpHierFileStruct->hbmMem2) + SelectObject(lpHierFileStruct->hdcMem2, lpHierFileStruct->hbmMem2); + lpHierFileStruct->hbmMem2 = NULL; + DeleteObject(lpHierFileStruct->hbmIcons2); + lpHierFileStruct->hbmIcons2 = NULL; + } + + if ( lpHierFileStruct->hdcMem2 ) { + DeleteDC(lpHierFileStruct->hdcMem2); + lpHierFileStruct->hdcMem2 = NULL; + } + +} // HierFile_DrawTerm + +VOID HierFile_DrawCloseAll(LPHEIRDRAWSTRUCT lpHierFileStruct ) { + lpHierFileStruct->NumOpened= 0; + if ( lpHierFileStruct->Opened ) { + _ffree(lpHierFileStruct->Opened); + } + lpHierFileStruct->Opened = NULL; +} // HierFile_DrawCloseAll + +VOID HierFile_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT FAR* lpMeasureItem, + LPHEIRDRAWSTRUCT lpHierFileStruct) { + lpMeasureItem->itemHeight = max(lpHierFileStruct->nBitmapHeight1, + lpHierFileStruct->nTextHeight); +} // HierFile_OnMeasureItem + +VOID HierFile_DrawSetTextHeight (HWND hwndList, HFONT hFont, LPHEIRDRAWSTRUCT lpHierFileStruct ) { + TEXTMETRIC TextMetrics; + HANDLE hOldFont=NULL; + HDC hdc; + + // + // This sure looks like a lot of work to find the character height + // + hdc = GetDC(hwndList); + + hOldFont = SelectObject(hdc, hFont); + GetTextMetrics(hdc, &TextMetrics); + SelectObject(hdc, hOldFont); + ReleaseDC(hwndList, hdc); + + lpHierFileStruct->nTextHeight = TextMetrics.tmHeight; + + lpHierFileStruct->nLineHeight = + max(lpHierFileStruct->nBitmapHeight1, lpHierFileStruct->nTextHeight); + + if ( hwndList != NULL ) + SendMessage(hwndList, LB_SETITEMHEIGHT, 0, + MAKELPARAM(lpHierFileStruct->nLineHeight, 0)); +} // HierFile_DrawSetTextHeight + +static DWORD near RGB2BGR(DWORD rgb) { + return RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb)); +} // RGB2BGR + + + +/* + * Creates the objects used while drawing the tree. This may be called + * repeatedly in the event of a WM_SYSCOLORCHANGED message. + */ + +BOOL HierFile_DrawInit(HINSTANCE hInstance, + int nBitmap1, + int nBitmap2, + int nRows, + int nColumns, + BOOL bLines, + LPHEIRDRAWSTRUCT lpHierFileStruct, + BOOL bInit) { + HANDLE hRes; + HANDLE hResMem; + LPBITMAPINFOHEADER lpbiReadOnly; + LPBITMAPINFOHEADER lpbiReadWrite; + DWORD FAR * lpColorTable; + LPSTR lpBits; + int biSize; + int bc; + HDC hDC; + + + if ( bInit ) { + lpHierFileStruct->NumOpened = 0; + lpHierFileStruct->Opened = NULL; + lpHierFileStruct->bLines = bLines; + } + + // If the Memory DC is not created yet do that first. + if (!lpHierFileStruct->hdcMem1) { + + // get a screen DC + hDC = GetDC(NULL); + + // Create a memory DC compatible with the screen + lpHierFileStruct->hdcMem1 = CreateCompatibleDC(hDC); + + // Release the Screen DC + ReleaseDC(NULL, hDC); + + if (!lpHierFileStruct->hdcMem1) + return FALSE; + + lpHierFileStruct->hbmMem1 = NULL; + } + + // If the Memory DC is not created yet do that first. + if (!lpHierFileStruct->hdcMem2) { + + // get a screen DC + hDC = GetDC(NULL); + + // Create a memory DC compatible with the screen + lpHierFileStruct->hdcMem2 = CreateCompatibleDC(hDC); + + // Release the Screen DC + ReleaseDC(NULL, hDC); + + if (!lpHierFileStruct->hdcMem2) + return FALSE; + + lpHierFileStruct->hbmMem2 = NULL; + } + + /*+----------------------------------------------------------------------------------+ + | For First Bitmap | + +----------------------------------------------------------------------------------+*/ + + // (Re)Load the Bitmap ( original from disk ) + + // Use the FindResource,LoadResource,LockResource since it makes it easy to get the + // pointer to the BITMAPINFOHEADER we need. + hRes = FindResource(hInstance, MAKEINTRESOURCE(nBitmap1), RT_BITMAP); + if (!hRes) + return FALSE; + + hResMem = LoadResource(hInstance, hRes); + if (!hResMem) + return FALSE; + + // Now figure out the bitmaps background color. + // This code assumes the lower left corner is a + // bit in the background color. + lpbiReadOnly = (LPBITMAPINFOHEADER)LockResource(hResMem); + if (!lpbiReadOnly) + return FALSE; + + // Determine size of bitmap information header plus color table entries + biSize = lpbiReadOnly->biSize + ((1 << (lpbiReadOnly->biBitCount)) * sizeof(RGBQUAD)); + + // Allocate copy of the bitmap information to munge on + lpbiReadWrite = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR, biSize); + if (!lpbiReadWrite) + return FALSE; + + memcpy(lpbiReadWrite, lpbiReadOnly, biSize); + + // Color table immediately follows bitmap information header + lpColorTable = (DWORD FAR *)((LPBYTE)lpbiReadWrite + lpbiReadWrite->biSize); + + // No need to munge bits so use original + lpBits = (LPBYTE)lpbiReadOnly + biSize; + + bc = (lpBits[0] & 0xF0) >> 4; // ASSUMES LOWER LEFT CORNER IS BG!! + + lpColorTable[bc] = RGB2BGR(GetSysColor(COLOR_WINDOW)); + + hDC = GetDC(NULL); + lpHierFileStruct->hbmIcons1 = CreateDIBitmap( + hDC, + lpbiReadWrite, + CBM_INIT, + lpBits, + (LPBITMAPINFO)lpbiReadWrite, + DIB_RGB_COLORS + ); + ReleaseDC(NULL, hDC); + + lpHierFileStruct->nBitmapHeight1 = (WORD)lpbiReadWrite->biHeight / nRows; + lpHierFileStruct->nBitmapWidth1 = (WORD)lpbiReadWrite->biWidth / nColumns; + + lpHierFileStruct->nLineHeight = + max(lpHierFileStruct->nBitmapHeight1, lpHierFileStruct->nTextHeight); + + GlobalFree(lpbiReadWrite); + UnlockResource(hResMem); + FreeResource(hResMem); + + if (!lpHierFileStruct->hbmIcons1) + return FALSE; + + lpHierFileStruct->hbmMem1 = SelectObject(lpHierFileStruct->hdcMem1, lpHierFileStruct->hbmIcons1); + if (!lpHierFileStruct->hbmMem1) + return FALSE; + + /*+----------------------------------------------------------------------+ + | For Second Bitmap | + +----------------------------------------------------------------------+*/ + + // (Re)Load the Bitmap ( original from disk ) + hRes = FindResource(hInstance, MAKEINTRESOURCE(nBitmap2), RT_BITMAP); + if (!hRes) + return FALSE; + + hResMem = LoadResource(hInstance, hRes); + if (!hResMem) + return FALSE; + + // Now figure out the bitmaps background color. + // This code assumes the lower left corner is a + // bit in the background color. + lpbiReadOnly = (LPBITMAPINFOHEADER) LockResource(hResMem); + if (!lpbiReadOnly) + return FALSE; + + // Determine size of bitmap information header plus color table entries + biSize = lpbiReadOnly->biSize + ((1 << (lpbiReadOnly->biBitCount)) * sizeof(RGBQUAD)); + + // Allocate copy of the bitmap information to munge on + lpbiReadWrite = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR, biSize); + if (!lpbiReadWrite) + return FALSE; + + memcpy(lpbiReadWrite, lpbiReadOnly, biSize); + + // Color table immediately follows bitmap information header + lpColorTable = (DWORD FAR *)((LPBYTE)lpbiReadWrite + lpbiReadWrite->biSize); + + // No need to munge bits so use original + lpBits = (LPBYTE)lpbiReadOnly + biSize; + + bc = (lpBits[0] & 0xF0) >> 4; // ASSUMES LOWER LEFT CORNER IS BG!! + + lpColorTable[bc] = RGB2BGR(GetSysColor(COLOR_WINDOW)); + + hDC = GetDC(NULL); + lpHierFileStruct->hbmIcons2 = CreateDIBitmap( + hDC, + lpbiReadWrite, + CBM_INIT, + lpBits, + (LPBITMAPINFO)lpbiReadWrite, + DIB_RGB_COLORS + ); + ReleaseDC(NULL, hDC); + + // These are hard-coded as 1 row and 3 columns for the checkbox bitmap + lpHierFileStruct->nBitmapHeight2 = (WORD)lpbiReadWrite->biHeight / 1; + lpHierFileStruct->nBitmapWidth2 = (WORD)lpbiReadWrite->biWidth / 3; + + GlobalFree(lpbiReadWrite); + UnlockResource(hResMem); + FreeResource(hResMem); + + if (!lpHierFileStruct->hbmIcons2) + return FALSE; + + lpHierFileStruct->hbmMem2 = SelectObject(lpHierFileStruct->hdcMem2, lpHierFileStruct->hbmIcons2); + if (!lpHierFileStruct->hbmMem2) + return FALSE; + + return TRUE; +} // HierFile_DrawInit + + +BOOL HierFile_InCheck(int nLevel, int xPos, LPHEIRDRAWSTRUCT lpHierFileStruct) { + WORD wIndent; + + wIndent = ((int)(nLevel) * lpHierFileStruct->nBitmapWidth1) + XBMPOFFSET; + + if ((xPos > wIndent) && (xPos < wIndent + lpHierFileStruct->nBitmapWidth2)) + return TRUE; + + return FALSE; + +} // HierFile_InCheck + + +VOID HierFile_OnDrawItem(HWND hwnd, + const DRAWITEMSTRUCT FAR* lpDrawItem, + int nLevel, + DWORD dwConnectLevel, + TCHAR *szText, + int nRow, + int nColumn, + int nColumn2, + LPHEIRDRAWSTRUCT lpHierFileStruct) { + HDC hDC; + WORD wIndent, wTopBitmap, wTopText; + RECT rcTemp; + + + if ( lpDrawItem->itemID == (UINT)-1 ) + return ; + + hDC = lpDrawItem->hDC; + CopyRect(&rcTemp, &lpDrawItem->rcItem); + + wIndent = rcTemp.left + ((int)(nLevel) * lpHierFileStruct->nBitmapWidth1) + XBMPOFFSET; + rcTemp.left = wIndent + lpHierFileStruct->nBitmapWidth1 + lpHierFileStruct->nBitmapWidth2; + wTopText = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierFileStruct->nTextHeight / 2); + wTopBitmap = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierFileStruct->nBitmapHeight1 / 2); + + if (lpDrawItem->itemAction == ODA_FOCUS) + goto DealWithFocus; + else if (lpDrawItem->itemAction == ODA_SELECT) + goto DealWithSelection; + + /*+-----------------------------------------------------------------------+ + | Connecting Line code | + +-----------------------------------------------------------------------+*/ + if (lpHierFileStruct->bLines && nLevel) { + DWORD dwMask = 1; + int nTempLevel; + int x,y; + + // draw lines in text color + SetBkColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); + + // Draw a series of | lines for outer levels + x = lpHierFileStruct->nBitmapWidth1 / 2 + XBMPOFFSET; + + for ( nTempLevel = 0; nTempLevel < nLevel ; nTempLevel++) + { + if ( dwConnectLevel & dwMask ) + FastRect(hDC, x, rcTemp.top, 1, rcTemp.bottom - rcTemp.top); + + x += lpHierFileStruct->nBitmapWidth2; + dwMask *= 2; + } + + + // Draw the short vert line up towards the parent + nTempLevel = nLevel-1; + dwMask *= 2; + + x = nTempLevel * lpHierFileStruct->nBitmapWidth1 + lpHierFileStruct->nBitmapWidth1 / 2 + XBMPOFFSET; + + if ( dwConnectLevel & dwMask ) + y = rcTemp.bottom; + else + y = rcTemp.bottom - lpHierFileStruct->nLineHeight / 2; + + FastRect(hDC, x, rcTemp.top, 1, y - rcTemp.top); + + // Draw short horiz bar to right + FastRect(hDC, x, rcTemp.bottom-lpHierFileStruct->nLineHeight / 2, lpHierFileStruct->nBitmapWidth1 / 2, 1); + } + + /*+-----------------------------------------------------------------------+ + | Bitmaps | + +-----------------------------------------------------------------------+*/ + // Draw the checkbox bitmap + BitBlt(hDC, + wIndent, wTopBitmap, + lpHierFileStruct->nBitmapWidth2, lpHierFileStruct->nBitmapHeight2, + lpHierFileStruct->hdcMem2, + nColumn2 * lpHierFileStruct->nBitmapWidth2, + 0 * lpHierFileStruct->nBitmapHeight2, + SRCCOPY); + + // Now the other app specific bitmap adjusted over for the checkbox bitmap + BitBlt(hDC, + wIndent + lpHierFileStruct->nBitmapWidth2, wTopBitmap, + lpHierFileStruct->nBitmapWidth1, lpHierFileStruct->nBitmapHeight1, + lpHierFileStruct->hdcMem1, + nColumn * lpHierFileStruct->nBitmapWidth1, + nRow * lpHierFileStruct->nBitmapHeight1, + SRCCOPY); + +DealWithSelection: + + if (lpDrawItem->itemState & ODS_SELECTED) { + SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } else { + SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); + SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); + } + + + ExtTextOut(hDC, rcTemp.left + 1, wTopText, ETO_CLIPPED | ETO_OPAQUE, + &rcTemp, szText, lstrlen(szText), NULL); + + if (lpDrawItem->itemState & ODS_FOCUS && lpDrawItem->itemAction != ODA_SELECT) { +DealWithFocus: + DrawFocusRect(hDC, &rcTemp); + } + + +} // HierFile_OnDrawItem + + +// draw a solid color rectangle quickly +static VOID near FastRect(HDC hDC, int x, int y, int cx, int cy) { + RECT rc; + + rc.left = x; + rc.right = x+cx; + rc.top = y; + rc.bottom = y+cy; + ExtTextOut(hDC,x,y,ETO_OPAQUE,&rc,NULL,0,NULL); +} // FastRect + + +BOOL HierFile_IsOpened(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData) { + // For Now just a dumb search + // + int Count; + + for ( Count = 0; Count < lpHierFileStruct->NumOpened; Count++ ) { + if ( lpHierFileStruct->Opened[Count] == dwData ) { + return TRUE; + } + } + + return FALSE; + +} // HierFile_IsOpened + + +VOID HierFile_OpenItem(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData) { + lpHierFileStruct->NumOpened++; + + if (lpHierFileStruct->Opened == NULL ) + lpHierFileStruct->Opened = + (DWORD FAR *)_fmalloc(sizeof(DWORD)*lpHierFileStruct->NumOpened); + else + lpHierFileStruct->Opened = + (DWORD FAR *)_frealloc(lpHierFileStruct->Opened, + sizeof(DWORD)*lpHierFileStruct->NumOpened); + + lpHierFileStruct->Opened[lpHierFileStruct->NumOpened-1] = dwData; +} // HierFile_OpenItem + +VOID HierFile_CloseItem(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData) { + // For Now just a dumb search + // + int Count; + + for ( Count = 0; Count < lpHierFileStruct->NumOpened; Count++ ) { + if ( lpHierFileStruct->Opened[Count] == dwData ) { + if (--lpHierFileStruct->NumOpened == 0 ) { + _ffree(lpHierFileStruct->Opened); + lpHierFileStruct->Opened = NULL; + } + else { + if ( Count < lpHierFileStruct->NumOpened ) { + _fmemmove(&(lpHierFileStruct->Opened[Count]), + &(lpHierFileStruct->Opened[Count+1]), + sizeof(DWORD)*(lpHierFileStruct->NumOpened-Count)); + } + lpHierFileStruct->Opened = + (DWORD FAR *)_frealloc(lpHierFileStruct->Opened, + sizeof(DWORD)*lpHierFileStruct->NumOpened); + } + } + } +} // HierFile_CloseItem + + +VOID HierFile_ShowKids(LPHEIRDRAWSTRUCT lpHierFileStruct, + HWND hwndList, WORD wCurrentSelection, WORD wKids) { + WORD wBottomIndex; + WORD wTopIndex; + WORD wNewTopIndex; + WORD wExpandInView; + RECT rc; + + wTopIndex = (WORD)SendMessage(hwndList, LB_GETTOPINDEX, 0, 0L); + GetClientRect(hwndList, &rc); + wBottomIndex = wTopIndex + (rc.bottom+1) / lpHierFileStruct->nLineHeight; + + wExpandInView = (wBottomIndex - wCurrentSelection); + + if (wKids >= wExpandInView) { + wNewTopIndex = min(wCurrentSelection, wTopIndex + wKids - wExpandInView + 1); + SendMessage(hwndList, LB_SETTOPINDEX, (WORD)wNewTopIndex, 0L); + } + +} // HierFile_ShowKids diff --git a/private/nw/convert/nwconv/hierfile.h b/private/nw/convert/nwconv/hierfile.h new file mode 100644 index 000000000..55baa9cea --- /dev/null +++ b/private/nw/convert/nwconv/hierfile.h @@ -0,0 +1,74 @@ +#define XBMPOFFSET 2 + + +typedef struct _HierFileStruct { + HDC hdcMem1; + HDC hdcMem2; + HBITMAP hbmIcons1; + HBITMAP hbmMem1; + int nBitmapHeight1; + int nBitmapWidth1; + HBITMAP hbmIcons2; + HBITMAP hbmMem2; + int nBitmapHeight2; + int nBitmapWidth2; + int nTextHeight; + int nLineHeight; + BOOL bLines; + int NumOpened; + DWORD FAR *Opened; + +} HEIRDRAWSTRUCT; + +typedef HEIRDRAWSTRUCT FAR * LPHEIRDRAWSTRUCT ; + + +// +// Interface functions +// +VOID HierFile_DrawTerm(LPHEIRDRAWSTRUCT lpHierFileStruct); + +VOID HierFile_DrawSetTextHeight (HWND hwnd, HFONT hFont, LPHEIRDRAWSTRUCT lpHierFileStruct ); + +BOOL HierFile_DrawInit(HINSTANCE hInstance, + int nBitmap1, + int nBitmap2, + int nRows, + int nColumns, + BOOL bLines, + LPHEIRDRAWSTRUCT lpHierFileStruct, + BOOL bInit); + + +VOID HierFile_OnDrawItem(HWND hwnd, + const DRAWITEMSTRUCT FAR* lpDrawItem, + int nLevel, + DWORD dwConnectLevel, + TCHAR *szText, + int nRow, + int nColumn, + int nColumn2, + LPHEIRDRAWSTRUCT lpHierFileStruct); + + +VOID HierFile_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT FAR* lpMeasureItem, + LPHEIRDRAWSTRUCT lpHierFileStruct); + +BOOL HierFile_IsOpened(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData); + +VOID HierFile_OpenItem(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData); + +VOID HierFile_CloseItem(LPHEIRDRAWSTRUCT lpHierFileStruct, DWORD dwData); + +VOID HierFile_DrawCloseAll(LPHEIRDRAWSTRUCT lpHierFileStruct ); + +VOID HierFile_ShowKids(LPHEIRDRAWSTRUCT lpHierFileStruct, + HWND hwndList, WORD wCurrentSelection, WORD wKids); + +BOOL HierFile_InCheck(int nLevel, int xPos, LPHEIRDRAWSTRUCT lpHierFileStruct); + +// +// Support functions +// +static VOID near FastRect(HDC hDC, int x, int y, int cx, int cy); +static DWORD near RGB2BGR(DWORD rgb); diff --git a/private/nw/convert/nwconv/hiericon.bmp b/private/nw/convert/nwconv/hiericon.bmp new file mode 100644 index 000000000..c4d0b5af3 Binary files /dev/null and b/private/nw/convert/nwconv/hiericon.bmp differ diff --git a/private/nw/convert/nwconv/loghours.c b/private/nw/convert/nwconv/loghours.c new file mode 100644 index 000000000..5276767a5 --- /dev/null +++ b/private/nw/convert/nwconv/loghours.c @@ -0,0 +1,310 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + loghours.c + +Abstract: + + Private routines to support rotation of logon hours between local time + and GMT time. + +Author: + + Cliff Van Dyke (cliffv) 16-Mar-93 + +Environment: + + User mode only. + Contains NT-specific code. + Requires ANSI C extensions: slash-slash comments, long external names. + +Revision History: + +--*/ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + + + +BOOLEAN +NetpRotateLogonHoursPhase1( + IN BOOL ConvertToGmt, + OUT PULONG RotateCount + ) + +/*++ + +Routine Description: + + Determine the amount to rotate the logon hours by to convert to/from GMT + +Arguments: + + ConvertToGmt - + True to convert the logon hours from local time to GMT relative + False to convert the logon hours from GMT relative to local time + + RotateCount - Returns the number of bits to shift by. + +Return Value: + + TRUE if the RotateCount could be computed + FALSE if a RotateCount could not be computed + +--*/ +{ + RTL_TIME_ZONE_INFORMATION tzi; + LONG BiasInHours; + NTSTATUS Status; + + // + // Get the timezone data from the registry + // + + Status = RtlQueryTimeZoneInformation( &tzi ); + if ( !NT_SUCCESS(Status) ) { + return FALSE; + } + + // + // Compute the amount to rotate the logon hours by + // + // Round the bias in minutes to the closest bias in hours. + // Take into consideration that Bias can be negative. + // Do this by forcing the Bias to be positive, rounding, + // then adjusting it back negative again. + // + + ASSERT( tzi.Bias > -(24*60) ); + BiasInHours = ((tzi.Bias + (24*60) + 30)/60) - 24; + + if ( !ConvertToGmt ) { + BiasInHours = - BiasInHours; + } + + *RotateCount = BiasInHours; + return TRUE; + +} + + +BOOLEAN +NetpRotateLogonHoursPhase2( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN LONG RotateCount + ) + +/*++ + +Routine Description: + + Rotate the LogonHours bit mask by the required amount. + + +Arguments: + + LogonHours - Pointer to LogonHour bit mask + + UnitsPerWeek - Number of bits in the bit mask. Must be UNITS_PER_WEEK (168). + + RotateCount - Number of bits to rotate by. Must be between 31 and -31. + Negative means to rotate left. + Positive means to rotate right. + +Return Value: + + TRUE if the rotation succeeded. + FALSE if a parameter was out of range + +--*/ +{ + // + // Useful constants + // + +#define DWORDS_PER_WEEK ((UNITS_PER_WEEK+31)/32) +#define BYTES_PER_WEEK (UNITS_PER_WEEK/8) + + DWORD AlignedLogonHours[DWORDS_PER_WEEK+1]; + LONG i; + + BOOLEAN RotateLeft; + + // + // Ensure there are 8 bits per byte, + // 32 bits per DWORD and + // units per week is even number of bytes. + // + + ASSERT( CHAR_BIT == 8 ); + ASSERT( sizeof(DWORD) * CHAR_BIT == 32 ); + ASSERT( UNITS_PER_WEEK/8*8 == UNITS_PER_WEEK ); + + + // + // Validate the input parameters + // + + if ( UnitsPerWeek != UNITS_PER_WEEK ) { + ASSERT( UnitsPerWeek == UNITS_PER_WEEK ); + return FALSE; + } + + if ( RotateCount == 0 ) { + return TRUE; + } + + RotateLeft = (RotateCount < 0); + RotateCount = labs( RotateCount ); + if ( RotateCount > 31 ) { + ASSERT ( RotateCount <= 31 ); + return FALSE; + } + + + // + // Do the left rotate. + // + + if (RotateLeft) { + + + // + // Copy the logon hours to a DWORD aligned buffer. + // + // Duplicate the first dword at the end of the buffer to make + // the rotation code trivial. + // + + RtlCopyMemory(AlignedLogonHours, LogonHours, BYTES_PER_WEEK ); + + RtlCopyMemory( ((PBYTE)AlignedLogonHours)+BYTES_PER_WEEK, + LogonHours, + sizeof(DWORD) ); + + // + // Actually rotate the data. + // + + for ( i=0; i < DWORDS_PER_WEEK; i++ ) { + AlignedLogonHours[i] = + (AlignedLogonHours[i] >> RotateCount) | + (AlignedLogonHours[i+1] << (32-RotateCount)); + } + + // + // Copy the logon hours back to the input buffer. + // + + RtlCopyMemory( LogonHours, AlignedLogonHours, BYTES_PER_WEEK ); + + + // + // Do the right rotate. + // + + } else { + + + // + // Copy the logon hours to a DWORD aligned buffer. + // + // Duplicate the last DWORD at the front of the buffer to make + // the rotation code trivial. + // + + RtlCopyMemory( &AlignedLogonHours[1], LogonHours, BYTES_PER_WEEK ); + RtlCopyMemory( AlignedLogonHours, + &LogonHours[BYTES_PER_WEEK-4], + sizeof(DWORD)); + + // + // Actually rotate the data. + // + + for ( i=DWORDS_PER_WEEK-1; i>=0; i-- ) { + AlignedLogonHours[i+1] = + (AlignedLogonHours[i+1] << RotateCount) | + (AlignedLogonHours[i] >> (32-RotateCount)); + } + + // + // Copy the logon hours back to the input buffer. + // + + RtlCopyMemory( LogonHours, &AlignedLogonHours[1], BYTES_PER_WEEK ); + + } + + // + // Done + // + + return TRUE; + +} + + + +BOOLEAN +NetpRotateLogonHours( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN BOOL ConvertToGmt + ) + +/*++ + +Routine Description: + + Rotate the LogonHours bit mask to/from GMT relative time. + + +Arguments: + + LogonHours - Pointer to LogonHour bit mask + + UnitsPerWeek - Number of bits in the bit mask. Must be UNITS_PER_WEEK (168). + + ConvertToGmt - + True to convert the logon hours from local time to GMT relative + False to convert the logon hours from GMT relative to local time + +Return Value: + + TRUE if the rotation succeeded. + FALSE if a parameter was out of range + +--*/ +{ + ULONG RotateCount; + + // + // Break the functionality into two phases so that if the caller is doing + // this multiple time, he just calls Phase 1 once and Phase 2 multiple + // times. + // + + if ( !NetpRotateLogonHoursPhase1( ConvertToGmt, &RotateCount ) ) { + return FALSE; + } + + return NetpRotateLogonHoursPhase2( LogonHours, UnitsPerWeek, RotateCount ); + +} diff --git a/private/nw/convert/nwconv/loghours.h b/private/nw/convert/nwconv/loghours.h new file mode 100644 index 000000000..b6dfc11dd --- /dev/null +++ b/private/nw/convert/nwconv/loghours.h @@ -0,0 +1,52 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + loghours.h + +Abstract: + + Private routines to support rotation of logon hours between local time + and GMT time. + +Author: + + Cliff Van Dyke (cliffv) 16-Mar-93 + +Environment: + + User mode only. + Contains NT-specific code. + Requires ANSI C extensions: slash-slash comments, long external names. + +Revision History: + +--*/ + + + +// +// Procedure forwards from loghours.c +// + +BOOLEAN +NetpRotateLogonHoursPhase1( + IN BOOL ConvertToGmt, + OUT PULONG RotateCount + ); + +BOOLEAN +NetpRotateLogonHoursPhase2( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN LONG RotateCount + ); + +BOOLEAN +NetpRotateLogonHours( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN BOOL ConvertToGmt + ); diff --git a/private/nw/convert/nwconv/makefile b/private/nw/convert/nwconv/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/nw/convert/nwconv/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/nw/convert/nwconv/map.c b/private/nw/convert/nwconv/map.c new file mode 100644 index 000000000..74530ca84 --- /dev/null +++ b/private/nw/convert/nwconv/map.c @@ -0,0 +1,1682 @@ +/* + +-------------------------------------------------------------------------+ + | User Options Dialog | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [MAP.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Sep 28, 1994] | + | Last Update : [Sep 28, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Sep 28, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "map.h" +#include "nwlog.h" +#include "nwconv.h" + +// from userdlg.c +DWORD UserFileGet(HWND hwnd, LPTSTR FilePath); + +// The map file is kept as a doubly-linked list of sections, each of which has +// a doubly-linked list of lines in that section. A header is used to point to +// the first section, and also contains a pointer to any lines that appear +// before the first section (usually only comment lines) - it also keeps the +// current line and section pointer. +// +// All the linked lists have a dummy header and tail, with the tail pointing +// back on itself (this simplifies the logic for list manipulation)... +// +// +-------------+ +----------------+ +// | Dummy | | Dummy | +// | head node v v tail node | +// | +-----------+ +-----------+ +-----------+ | +// | | Node 1 |-->| Node 2 |-->| Node 3 |----+ +// +--| (not used)|<--| (data) |<--| (not used)| +// +-----------+ +-----------+ +-----------+ +// +// The dummy head/tail nodes make it easy to keep track of the start and +// end of the list (we never have to worry about updating the head and tail +// pointers in the owning data structures, since they never change). It does, +// however, make for some obtuse cases in the add/delete node code. + +typedef struct _LINKED_LIST { + struct _LINKED_LIST *prev; + struct _LINKED_LIST *next; + +} LINKED_LIST; + +typedef struct _LINK_HEAD { + LINKED_LIST *Head; + LINKED_LIST *Tail; + + LINKED_LIST *Current; + ULONG Count; + + TCHAR Name[]; +} LINK_HEAD; + + +static TCHAR MappingFile[MAX_PATH + 1]; +static TCHAR PasswordConstant[MAX_PW_LEN + 1]; +static BOOL DoUsers = TRUE; +static BOOL DoGroups = TRUE; +static UINT PasswordOption = 0; +static LPTSTR SourceServ; + +/*+-------------------------------------------------------------------------+ + | Common Linked List Routines + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ll_Init() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_Init(ULONG Size) { + LINKED_LIST *llHead; + LINKED_LIST *llTail; + + llHead = (LINKED_LIST *) AllocMemory(Size); + if (llHead == NULL) + return NULL; + + llTail = (LINKED_LIST *) AllocMemory(Size); + if (llTail == NULL) { + FreeMemory(llHead); + return NULL; + } + + llHead->prev = llHead; + llHead->next = llTail; + + llTail->next = llTail; + llTail->prev = llHead; + + return llHead; + +} // ll_Init + + +/*+-------------------------------------------------------------------------+ + | ll_Next() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_Next(void *vllCurrent) { + LINKED_LIST *llCurrent; + + llCurrent = (LINKED_LIST *) vllCurrent; + + if ((llCurrent == NULL) || (llCurrent->next == NULL) || (llCurrent->prev == NULL)) + return NULL; + + llCurrent = llCurrent->next; + + if (llCurrent->next == llCurrent) + return NULL; + else + return llCurrent; + +} // ll_Next + + +/*+-------------------------------------------------------------------------+ + | ll_Prev() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_Prev(void *vllCurrent) { + LINKED_LIST *llCurrent; + + llCurrent = (LINKED_LIST *) vllCurrent; + + if ((llCurrent == NULL) || (llCurrent->next == NULL) || (llCurrent->prev == NULL)) + return NULL; + + llCurrent = llCurrent->prev; + + if (llCurrent->prev == llCurrent) + return NULL; + else + return llCurrent; + +} // ll_Prev + + +/*+-------------------------------------------------------------------------+ + | ll_InsertAfter() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_InsertAfter(void *vllCurrent, void *vllNew) { + LINKED_LIST *llCurrent; + LINKED_LIST *llNew; + + llCurrent = (LINKED_LIST *) vllCurrent; + llNew = (LINKED_LIST *) vllNew; + + if ((vllCurrent == NULL) || (llNew == NULL)) + return NULL; + + // change pointers to insert it into the list + llNew->next = llCurrent->next; + + // check if at end of list + if (llCurrent->next == llCurrent) + llNew->prev = llCurrent->prev; + else + llNew->prev = llCurrent; + + llNew->prev->next = llNew; + llNew->next->prev = llNew; + return llNew; +} // ll_InsertAfter + + +/*+-------------------------------------------------------------------------+ + | ll_InsertBefore() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_InsertBefore(void *vllCurrent, void *vllNew) { + LINKED_LIST *llCurrent; + LINKED_LIST *llNew; + + llCurrent = (LINKED_LIST *) vllCurrent; + llNew = (LINKED_LIST *) vllNew; + + if ((vllCurrent == NULL) || (llNew == NULL)) + return NULL; + + // change pointers to insert it into the list + llNew->prev = llCurrent->prev; + + // check if at start of list + if (llCurrent->prev = llCurrent) + llNew->next = llCurrent->next; + else + llNew->next = llCurrent; + + llNew->prev->next = llNew; + llNew->next->prev = llNew; + return llNew; +} // ll_InsertBefore + + +/*+-------------------------------------------------------------------------+ + | ll_Delete() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_Delete(void *vllCurrent) { + LINKED_LIST *llCurrent; + + llCurrent = (LINKED_LIST *) vllCurrent; + + if ((llCurrent == NULL) || (llCurrent->next == NULL) || (llCurrent->prev == NULL)) + return NULL; + + // make sure not on one of the dummy end headers + if ((llCurrent->next == llCurrent) || (llCurrent->prev == llCurrent)) + return NULL; + + // changed pointers to remove it from list + llCurrent->prev->next = llCurrent->next; + llCurrent->next->prev = llCurrent->prev; + + // Get which one to return as new current record - we generally want to + // go to the previous record - unless we deleted the first record, in + // which case get the next record. If there are no records, then return + // the list head + llCurrent = llCurrent->prev; + + // check if at start of list + if (llCurrent->prev == llCurrent) + llCurrent = llCurrent->next; + + // make sure not at end of list (may have moved here if empty list) - if + // so we want to return the starting node + if (llCurrent->next == llCurrent) + llCurrent = llCurrent->prev; + + return llCurrent; +} // ll_Delete + + +/*+-------------------------------------------------------------------------+ + | ll_Home() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_Home(void *vllCurrent) { + LINKED_LIST *llCurrent; + + llCurrent = (LINKED_LIST *) vllCurrent; + if (llCurrent == NULL) + return (LINKED_LIST *) NULL; + + // make sure at start of list + while (llCurrent->prev != llCurrent) + llCurrent = llCurrent->prev; + + return llCurrent; + +} // ll_Home + + +/*+-------------------------------------------------------------------------+ + | ll_End() + | + +-------------------------------------------------------------------------+*/ +LINKED_LIST *ll_End(void *vllCurrent) { + LINKED_LIST *llCurrent; + + llCurrent = (LINKED_LIST *) vllCurrent; + if (llCurrent == NULL) + return (LINKED_LIST *) NULL; + + // make sure at end of list + while (llCurrent->next != llCurrent) + llCurrent = llCurrent->next; + + return llCurrent; + +} // ll_End + + +/*+-------------------------------------------------------------------------+ + | ll_ListFree() + | + +-------------------------------------------------------------------------+*/ +void ll_ListFree(void *vllHead) { + LINKED_LIST *llCurrent; + LINKED_LIST *llNext; + + llCurrent = (LINKED_LIST *) vllHead; + if (llCurrent == NULL) + return; + + // make sure at start of list + while (llCurrent->prev != llCurrent) + llCurrent = llCurrent->prev; + + // walk the chain - freeing it + while ((llCurrent != NULL) && (llCurrent->next != llCurrent)) { + llNext = llCurrent->next; + FreeMemory(llCurrent); + llCurrent = llNext; + } + + // at the ending node - kill it as well + FreeMemory(llCurrent); + +} // ll_ListFree + + + + +/*+-------------------------------------------------------------------------+ + | List Routines + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | map_LineListInit() + | + +-------------------------------------------------------------------------+*/ +MAP_LINE *map_LineListInit() { + MAP_LINE *NewHead; + MAP_LINE *NewTail; + + // Create our linked list + NewHead = (MAP_LINE *) ll_Init(sizeof(MAP_LINE)); + if (NewHead == NULL) + return (MAP_LINE *) NULL; + + NewTail = NewHead->next; + + // Now init them as appropriate + NewHead->Line = NULL; + NewTail->Line = NULL; + + return NewHead; + +} // map_LineListInit + + +/*+-------------------------------------------------------------------------+ + | map_SectionListInit() + | + +-------------------------------------------------------------------------+*/ +MAP_SECTION *map_SectionListInit() { + MAP_SECTION *NewHead; + MAP_SECTION *NewTail; + + // Create our linked list + NewHead = (MAP_SECTION *) ll_Init(sizeof(MAP_SECTION)); + if (NewHead == NULL) + return (MAP_SECTION *) NULL; + + NewTail = NewHead->next; + + // Now init them as appropriate + NewHead->Name = NULL; + NewTail->Name = NULL; + + NewHead->FirstLine = NewHead->LastLine = NewTail->FirstLine = NewTail->LastLine = NULL; + NewHead->LineCount = NewTail->LineCount = 0; + + return NewHead; + +} // map_SectionListInit + + +/*+-------------------------------------------------------------------------+ + | map_LineListFree() + | + +-------------------------------------------------------------------------+*/ +void map_LineListFree(MAP_LINE *CurrentLine) { + MAP_LINE *NextLine; + + if (CurrentLine == NULL) + return; + + // make sure at start of list + while (CurrentLine->prev != CurrentLine) + CurrentLine = CurrentLine->prev; + + // walk the chain - freeing it + while ((CurrentLine != NULL) && (CurrentLine->next != CurrentLine)) { + NextLine = CurrentLine->next; + + if (CurrentLine->Line != NULL) + FreeMemory(CurrentLine->Line); + + FreeMemory(CurrentLine); + CurrentLine = NextLine; + } + + // at the ending node - kill it as well + FreeMemory(CurrentLine); + +} // map_LineListFree + + +/*+-------------------------------------------------------------------------+ + | map_SectionListFree() + | + +-------------------------------------------------------------------------+*/ +void map_SectionListFree(MAP_SECTION *CurrentSection) { + MAP_SECTION *NextSection; + + if (CurrentSection == NULL) + return; + + // make sure at start of list + while (CurrentSection->prev != CurrentSection) + CurrentSection = CurrentSection->prev; + + // walk the chain - freeing it + while ((CurrentSection != NULL) && (CurrentSection->next != CurrentSection)) { + NextSection = CurrentSection->next; + + map_LineListFree(CurrentSection->FirstLine); + + if (CurrentSection->Name != NULL) + FreeMemory(CurrentSection->Name); + + FreeMemory(CurrentSection); + CurrentSection = NextSection; + } + + // at the ending node - kill it as well + FreeMemory(CurrentSection); + +} // map_SectionListFree + + + + +/*+-------------------------------------------------------------------------+ + | Section Routines + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | map_SectionInit() + | + +-------------------------------------------------------------------------+*/ +MAP_SECTION *map_SectionInit(LPTSTR Section) { + MAP_SECTION *NewSection; + MAP_LINE *FirstLine; + + NewSection = (MAP_SECTION *) AllocMemory(sizeof(MAP_SECTION)); + if (NewSection == NULL) + return (MAP_SECTION *) NULL; + + // Init the section name + NewSection->Name = (LPTSTR) AllocMemory((lstrlen(Section) + 1) * sizeof(TCHAR)); + + if (NewSection->Name == NULL) { + FreeMemory(NewSection); + return (MAP_SECTION *) NULL; + } + + // Now create the line list + FirstLine = map_LineListInit(); + if (FirstLine == NULL) { + FreeMemory(NewSection->Name); + FreeMemory(NewSection); + return (MAP_SECTION *) NULL; + } + + lstrcpy(NewSection->Name, Section); + NewSection->LineCount = 0; + NewSection->FirstLine = FirstLine; + NewSection->LastLine = FirstLine->next; + + return NewSection; +} // map_SectionInit + + +/*+-------------------------------------------------------------------------+ + | map_SectionAdd() + | + +-------------------------------------------------------------------------+*/ +void map_SectionAdd(MAP_FILE *hMap, LPTSTR Section) { + MAP_SECTION *NewSection; + + NewSection = map_SectionInit(Section); + if (NewSection == NULL) + return; + + // Add it to the section list + ll_InsertBefore((void *) hMap->LastSection, (void *) NewSection); + + // Init it so the added section is currently selected + hMap->CurrentSection = NewSection; + hMap->CurrentLine = hMap->CurrentSection->FirstLine; + +} // map_SectionAdd + + +/*+-------------------------------------------------------------------------+ + | map_SectionDelete() + | + +-------------------------------------------------------------------------+*/ +void map_SectionDelete(MAP_FILE *hMap) { + MAP_SECTION *CurrentSection; + MAP_SECTION *NewSection; + + // if no section is currently selected then get out + CurrentSection = hMap->CurrentSection; + if (CurrentSection == NULL) + return; + + // Remove this from the chain + NewSection = (MAP_SECTION *) ll_Delete((void *) CurrentSection); + + // walk the lines and remove them... + map_LineListFree(CurrentSection->FirstLine); + + // All lines have been removed, so remove section header itself + FreeMemory(CurrentSection->Name); + FreeMemory(CurrentSection); + + // Update Section count + if (hMap->SectionCount > 0) + hMap->SectionCount--; + +} // map_SectionDelete + + +/*+-------------------------------------------------------------------------+ + | map_SectionInsertBefore() + | + +-------------------------------------------------------------------------+*/ +void map_SectionInsertBefore(MAP_FILE *hMap, LPTSTR Section) { + MAP_SECTION *CurrentSection; + + if (hMap->CurrentSection == NULL) + return; + + CurrentSection = map_SectionInit(Section); + if (CurrentSection == NULL) + return; + + ll_InsertBefore((void *) hMap->CurrentSection, (void *) CurrentSection); + +} // map_SectionInsertBefore + + +/*+-------------------------------------------------------------------------+ + | map_SectionInsertAfter() + | + +-------------------------------------------------------------------------+*/ +void map_SectionInsertAfter(MAP_FILE *hMap, LPTSTR Section) { + MAP_SECTION *CurrentSection; + + if (hMap->CurrentSection == NULL) + return; + + CurrentSection = map_SectionInit(Section); + if (CurrentSection == NULL) + return; + + ll_InsertAfter((void *) hMap->CurrentSection, (void *) CurrentSection); + +} // map_SectionInsertAfter + + +/*+-------------------------------------------------------------------------+ + | map_SectionNext() + | + +-------------------------------------------------------------------------+*/ +MAP_SECTION *map_SectionNext(MAP_FILE *hMap) { + MAP_SECTION *CurrentSection; + + if (hMap->CurrentSection == NULL) + return NULL; + + CurrentSection = (MAP_SECTION *) ll_Next((void *) hMap->CurrentSection); + if (CurrentSection != NULL) + hMap->CurrentSection = CurrentSection; + + return CurrentSection; +} // map_SectionNext + + +/*+-------------------------------------------------------------------------+ + | map_SectionPrev() + | + +-------------------------------------------------------------------------+*/ +MAP_SECTION *map_SectionPrev(MAP_FILE *hMap) { + MAP_SECTION *CurrentSection; + + if (hMap->CurrentSection == NULL) + return NULL; + + CurrentSection = (MAP_SECTION *) ll_Prev((void *) hMap->CurrentSection); + + if (CurrentSection != NULL) + hMap->CurrentSection = CurrentSection; + + return CurrentSection; +} // map_SectionPrev + + +/*+-------------------------------------------------------------------------+ + | map_SectionFind() + | + +-------------------------------------------------------------------------+*/ +MAP_SECTION *map_SectionFind(MAP_FILE *hMap, LPTSTR Section) { + MAP_SECTION *CurrentSection; + + CurrentSection = hMap->FirstSection; + while (CurrentSection && lstrcmpi(CurrentSection->Name, Section)) + CurrentSection = (MAP_SECTION *) ll_Next((void *) CurrentSection); + + if (CurrentSection != NULL) { + hMap->CurrentSection = CurrentSection; + hMap->CurrentLine = hMap->CurrentSection->FirstLine; + } + + return CurrentSection; +} // map_SectionFind + + +/*+-------------------------------------------------------------------------+ + | map_SectionHome() + | + +-------------------------------------------------------------------------+*/ +void map_SectionHome(MAP_FILE *hMap) { + hMap->CurrentSection = hMap->FirstSection; + + hMap->CurrentLine = hMap->CurrentSection->FirstLine; +} // map_SectionHome + + +/*+-------------------------------------------------------------------------+ + | map_SectionEnd() + | + +-------------------------------------------------------------------------+*/ +void map_SectionEnd(MAP_FILE *hMap) { + MAP_SECTION *CurrentSection; + + CurrentSection = hMap->FirstSection; + while (CurrentSection && (CurrentSection->next != NULL)) + CurrentSection = CurrentSection->next; + + hMap->CurrentSection = CurrentSection; + hMap->CurrentLine = CurrentSection->FirstLine; +} // map_SectionEnd + + + + +/*+-------------------------------------------------------------------------+ + | Line Routines + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | map_LineInit() + | + +-------------------------------------------------------------------------+*/ +MAP_LINE *map_LineInit(LPTSTR Line) { + MAP_LINE *NewLine; + + NewLine = (MAP_LINE *) AllocMemory(sizeof(MAP_LINE)); + if (NewLine == NULL) + return (MAP_LINE *) NULL; + + NewLine->Line = (LPTSTR) AllocMemory((lstrlen(Line) + 1) * sizeof(TCHAR)); + + if (NewLine->Line == NULL) { + FreeMemory(NewLine); + return (MAP_LINE *) NULL; + } + + lstrcpy(NewLine->Line, Line); + return NewLine; + +} // map_LineInit + + +/*+-------------------------------------------------------------------------+ + | map_LineAdd() + | + +-------------------------------------------------------------------------+*/ +MAP_LINE *map_LineAdd(MAP_FILE *hMap, LPTSTR Line) { + MAP_LINE *NewLine; + + // make sure there is something to add it to + if ((hMap->CurrentSection == NULL) || (hMap->CurrentSection->LastLine == NULL)) + return (MAP_LINE *) NULL; + + // Create the new line + NewLine = map_LineInit(Line); + + if (NewLine->Line == NULL) + return (MAP_LINE *) NULL; + + // ...and add it to our list + ll_InsertBefore((void *) hMap->CurrentSection->LastLine, (void *) NewLine); + + // Init it so the added line is currently selected + hMap->CurrentLine = NewLine; + hMap->CurrentSection->LineCount++; + return NewLine; + +} // map_LineAdd + + +/*+-------------------------------------------------------------------------+ + | map_LineDelete() + | + +-------------------------------------------------------------------------+*/ +void map_LineDelete(MAP_FILE *hMap) { + MAP_LINE *CurrentLine; + MAP_LINE *NewLine; + + // if no section is currently selected then get out + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return; + + CurrentLine = hMap->CurrentLine; + NewLine = (MAP_LINE *) ll_Delete((void *) CurrentLine); + + // All lines have been removed, so remove section header itself + FreeMemory(CurrentLine->Line); + FreeMemory(CurrentLine); + + // update hMap + if (NewLine != NULL) + hMap->CurrentLine = NewLine; + else + hMap->CurrentLine = hMap->CurrentSection->FirstLine; + + if (hMap->CurrentSection->LineCount > 0) + hMap->CurrentSection->LineCount--; + +} // map_LineDelete + + +/*+-------------------------------------------------------------------------+ + | map_LineInsertBefore() + | + +-------------------------------------------------------------------------+*/ +void map_LineInsertBefore(MAP_FILE *hMap, LPTSTR Line) { + MAP_LINE *NewLine; + + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return; + + NewLine = map_LineInit(Line); + if (NewLine == NULL) + return; + + ll_InsertBefore((void *) hMap->CurrentLine, (void *) NewLine); +} // map_LineInsertBefore + + +/*+-------------------------------------------------------------------------+ + | map_LineInsertAfter() + | + +-------------------------------------------------------------------------+*/ +void map_LineInsertAfter(MAP_FILE *hMap, LPTSTR Line) { + MAP_LINE *NewLine; + + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return; + + NewLine = map_LineInit(Line); + if (NewLine == NULL) + return; + + ll_InsertAfter((void *) hMap->CurrentLine, (void *) NewLine); +} // map_LineInsertAfter + + +/*+-------------------------------------------------------------------------+ + | map_LineNext() + | + +-------------------------------------------------------------------------+*/ +MAP_LINE *map_LineNext(MAP_FILE *hMap) { + MAP_LINE *CurrentLine; + + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return NULL; + + CurrentLine = (MAP_LINE *) ll_Next((void *) hMap->CurrentLine); + if (CurrentLine != NULL) + hMap->CurrentLine = CurrentLine; + + return CurrentLine; +} // map_LineNext + + +/*+-------------------------------------------------------------------------+ + | map_LinePrev() + | + +-------------------------------------------------------------------------+*/ +MAP_LINE *map_LinePrev(MAP_FILE *hMap) { + MAP_LINE *CurrentLine; + + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return NULL; + + CurrentLine = (MAP_LINE *) ll_Prev((void *) hMap->CurrentLine); + if (CurrentLine != NULL) + hMap->CurrentLine = CurrentLine; + + return CurrentLine; +} // map_LinePrev + + +/*+-------------------------------------------------------------------------+ + | map_LineHome() + | + +-------------------------------------------------------------------------+*/ +void map_LineHome(MAP_FILE *hMap) { + + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return; + + hMap->CurrentLine = (MAP_LINE *) ll_Home((void *) hMap->CurrentLine); +} // map_LineHome + + +/*+-------------------------------------------------------------------------+ + | map_LineEnd() + | + +-------------------------------------------------------------------------+*/ +void map_LineEnd(MAP_FILE *hMap) { + if ((hMap->CurrentSection == NULL) || (hMap->CurrentLine == NULL)) + return; + + hMap->CurrentLine = (MAP_LINE *) ll_End((void *) hMap->CurrentLine); +} // map_LineEnd + + + + +/*+-------------------------------------------------------------------------+ + | Map File Routines + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | map_Home() + | + +-------------------------------------------------------------------------+*/ +void map_Home(MAP_FILE *hMap) { + hMap->CurrentSection = hMap->FirstSection; + +} // map_Home + + +/*+-------------------------------------------------------------------------+ + | map_End() + | + +-------------------------------------------------------------------------+*/ +void map_End(MAP_FILE *hMap) { + MAP_SECTION *CurrentSection; + MAP_LINE *CurrentLine = NULL; + + CurrentSection = hMap->FirstSection; + while (CurrentSection->next != NULL) + CurrentSection = CurrentSection->next; + + CurrentLine = CurrentSection->FirstLine; + + if (CurrentLine != NULL) + while (CurrentLine->next != NULL) + CurrentLine = CurrentLine->next; + + hMap->CurrentSection = CurrentSection; + hMap->CurrentLine = CurrentLine; +} // map_End + + +/*+-------------------------------------------------------------------------+ + | map_Open() + | + +-------------------------------------------------------------------------+*/ +MAP_FILE *map_Open(TCHAR *FileName) { + MAP_FILE *hMap = NULL; + HANDLE hFile = NULL; + char *FileCache = NULL; + char *chA; + char *pchA; + DWORD wrote; + char lpszA[MAX_LINE_LEN + 1]; + TCHAR lpsz[MAX_LINE_LEN + 1]; + TCHAR tmpStr[MAX_LINE_LEN + 1]; + char FileNameA[MAX_PATH + 1]; + ULONG Size; + TCHAR *ch; + TCHAR *pch; + TCHAR *lch; + DWORD FSize; + + MAP_SECTION *CurrentSection = NULL; + MAP_LINE *CurrentLine = NULL; + + WideCharToMultiByte(CP_ACP, 0, FileName, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + + hFile = CreateFileA( FileNameA, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == (HANDLE) INVALID_HANDLE_VALUE) + return hMap; + + FSize = GetFileSize(hFile, NULL); + + FileCache = (char *) AllocMemory(FSize + 1); + if (FileCache == NULL) + goto map_OpenExit; + + hMap = (MAP_FILE *) AllocMemory(sizeof(MAP_FILE) + ((lstrlen(FileName) + 1) * sizeof(TCHAR))); + if (hMap == NULL) + goto map_OpenExit; + + // Init the section list + CurrentSection = map_SectionListInit(); + if (CurrentSection == NULL) { + FreeMemory(hMap); + hMap = NULL; + goto map_OpenExit; + } + + hMap->FirstSection = CurrentSection; + hMap->CurrentSection = CurrentSection; + hMap->LastSection = CurrentSection->next; + + // Init the header info + if (hMap != NULL) { + hMap->hf = hFile; + hMap->Modified = FALSE; + hMap->CurrentLine = NULL; + hMap->SectionCount = 0; + + lstrcpy(hMap->Name, FileName); + } + + memset(FileCache, 0, FSize + 1); + + // Read in the whole file then parse it - it shouldn't be that large, a + // very full NW server generated ~20K map file + if (!ReadFile(hFile, FileCache, FSize, &wrote, NULL)) + goto map_OpenExit; + + // Now walk and parse the buffer - remember it's in ASCII + chA = FileCache; + while (*chA) { + // Get past any white space junk at beginning of line + while(*chA && ((*chA == ' ') || (*chA == '\t'))) + chA++; + + // transfer a line of text + Size = 0; + pchA = lpszA; + while (*chA && (*chA != '\n') && (*chA != '\r') && (Size < MAX_LINE_LEN)) + *pchA++ = *chA++; + + *pchA = '\0'; + if (*chA == '\r') + chA++; + if (*chA == '\n') + chA++; + + // ...convert line to Unicode + MultiByteToWideChar(CP_ACP, 0, lpszA, -1, lpsz, sizeof(lpsz) ); + + // + // Now have a line of text - figure out what it is and update data + // structures + // + + // ...Check for section header + ch = lpsz; + lch = pch = tmpStr; + if (*ch == TEXT(SECTION_BEGIN_CHAR)) { + // Find end section brace - keeping track of last non-white space char + // anything after end-section-brace is discarded. Any trailing/ + // leading whitespace in section header is removed + ch++; // get past section-begin + + // remove any leading whitespace + while(*ch && ((*ch == TEXT(' ')) || (*ch == TEXT('\t')))) + ch++; + + // transfer it to tmpStr (via pch pointer) + while (*ch && (*ch != TEXT(SECTION_END_CHAR))) { + // keep track of last non-whitespace + if ((*ch != TEXT(' ')) && (*ch != TEXT('\t'))) { + lch = pch; + lch++; + } + + *pch++ = *ch++; + } + + // NULL terminate before last section of whitespace + *lch = TEXT('\0'); + + // Allocate a new section-header block and init + map_SectionAdd(hMap, tmpStr); + } else { + // Not section header, so normal line - copy to tmpStr via pch pointer + while (*ch) { + // keep track of last non-whitespace + if ((*ch != TEXT(' ')) && (*ch != TEXT('\t'))) { + lch = pch; + lch++; + } + + *pch++ = *ch++; + } + + // NULL terminate before last section of whitespace + *lch = TEXT('\0'); + + // ...add it to the list + map_LineAdd(hMap, tmpStr); + } + + // Done with the line of text, so just loop back up to parse next + // line + } + +map_OpenExit: + + FreeMemory(FileCache); + return hMap; + +} // map_Open + + +/*+-------------------------------------------------------------------------+ + | map_Close() + | + +-------------------------------------------------------------------------+*/ +void map_Close(MAP_FILE *hMap) { + // If file modified then re-write file. + if ( hMap->Modified ) + ; + + // Write out cache of file, close it and clean up all the data structures + CloseHandle( hMap->hf ); + hMap = NULL; +} // map_Close + + +/*+-------------------------------------------------------------------------+ + | ParseWord() + | + +-------------------------------------------------------------------------+*/ +void ParseWord(TCHAR **lpch, LPTSTR tmpStr) { + TCHAR *ch; + TCHAR *lch; + TCHAR *pch; + + ch = *lpch; + lch = pch = tmpStr; + + // remove any leading whitespace + while(*ch && ((*ch == TEXT(' ')) || (*ch == TEXT('\t')))) + ch++; + + // transfer it to tmpStr (via pch pointer) + while (*ch && (*ch != TEXT(WORD_DELIMITER))) { + // keep track of last non-whitespace + if ((*ch != TEXT(' ')) && (*ch != TEXT('\t'))) { + lch = pch; + lch++; + } + + *pch++ = *ch++; + } + + if (*ch == TEXT(WORD_DELIMITER)) + ch++; + + // NULL terminate before last section of whitespace + *lch = TEXT('\0'); + *lpch = ch; + +} // ParseWord + + +/*+-------------------------------------------------------------------------+ + | map_ParseUser() + | + +-------------------------------------------------------------------------+*/ +void map_ParseUser(LPTSTR Line, LPTSTR Name, LPTSTR NewName, LPTSTR Password) { + TCHAR *pch = Line; + + lstrcpy(Name, TEXT("")); + lstrcpy(NewName, TEXT("")); + lstrcpy(Password, TEXT("")); + + if (Line == NULL) + return; + + ParseWord(&pch, Name); + if (lstrlen(Name) >= MAX_USER_NAME_LEN) + lstrcpy(Name, TEXT("")); + + ParseWord(&pch, NewName); + if (lstrlen(NewName) >= MAX_USER_NAME_LEN) + lstrcpy(NewName, TEXT("")); + + ParseWord(&pch, Password); + if (lstrlen(Password) > MAX_PW_LEN) + lstrcpy(Password, TEXT("")); + +} // map_ParseUser + + +/*+-------------------------------------------------------------------------+ + | map_ParseGroup() + | + +-------------------------------------------------------------------------+*/ +void map_ParseGroup(LPTSTR Line, LPTSTR Name, LPTSTR NewName) { + TCHAR *pch = Line; + + lstrcpy(Name, TEXT("")); + lstrcpy(NewName, TEXT("")); + + if (Line == NULL) + return; + + ParseWord(&pch, Name); + if (lstrlen(Name) >= MAX_GROUP_NAME_LEN) + lstrcpy(Name, TEXT("")); + + ParseWord(&pch, NewName); + if (lstrlen(NewName) >= MAX_GROUP_NAME_LEN) + lstrcpy(NewName, TEXT("")); + +} // map_ParseGroup + + +/*+-------------------------------------------------------------------------+ + | map_UsersEnum() + | + +-------------------------------------------------------------------------+*/ +DWORD map_UsersEnum(MAP_FILE *hMap, USER_LIST **lpUsers) { + DWORD ret = 0; + USER_LIST *UserList = NULL; + USER_BUFFER *UserBuffer = NULL; + MAP_SECTION *CurrentSection = NULL; + MAP_LINE *CurrentLine = NULL; + ULONG Entries = 0; + ULONG ActualEntries = 0; + TCHAR Name[MAX_LINE_LEN + 1]; + TCHAR NewName[MAX_LINE_LEN + 1]; + TCHAR Password[MAX_LINE_LEN + 1]; + ULONG i; + + CurrentSection = map_SectionFind(hMap, Lids(IDS_M_7)); + if (CurrentSection != NULL) + Entries = CurrentSection->LineCount; + + UserList = AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * Entries)); + + if (!UserList) { + ret = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = UserList->UserBuffer; + + for (i = 0; i < Entries; i++) { + CurrentLine = map_LineNext(hMap); + + if (CurrentLine != NULL) { + map_ParseUser(CurrentLine->Line, Name, NewName, Password); + + if (lstrlen(Name)) { + lstrcpy(UserBuffer[ActualEntries].Name, Name); + lstrcpy(UserBuffer[ActualEntries].NewName, NewName); + lstrcpy(UserBuffer[ActualEntries].Password, Password); + + if (lstrcmpi(Name, NewName)) + UserBuffer[ActualEntries].IsNewName = TRUE; + + ActualEntries++; + } + } + } + + if (ActualEntries != Entries) + UserList = (USER_LIST *) ReallocMemory((HGLOBAL) UserList, sizeof(USER_LIST) + (sizeof(USER_BUFFER)* ActualEntries)); + + if (UserList == NULL) + ret = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + UserBuffer = UserList->UserBuffer; + qsort((void *) UserBuffer, (size_t) ActualEntries, sizeof(USER_BUFFER), UserListCompare); + UserList->Count = ActualEntries; + } + + *lpUsers = UserList; + } + + return ret; +} // map_UsersEnum + + +/*+-------------------------------------------------------------------------+ + | map_GroupsEnum() + | + +-------------------------------------------------------------------------+*/ +DWORD map_GroupsEnum(MAP_FILE *hMap, GROUP_LIST **lpGroups) { + DWORD ret = 0; + GROUP_LIST *GroupList = NULL; + GROUP_BUFFER *GroupBuffer = NULL; + MAP_SECTION *CurrentSection = NULL; + MAP_LINE *CurrentLine = NULL; + ULONG Entries = 0; + ULONG ActualEntries = 0; + TCHAR Name[MAX_LINE_LEN + 1]; + TCHAR NewName[MAX_LINE_LEN + 1]; + ULONG i; + + + CurrentSection = map_SectionFind(hMap, Lids(IDS_M_8)); + if (CurrentSection != NULL) + Entries = CurrentSection->LineCount; + + GroupList = AllocMemory(sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER) * Entries)); + + if (!GroupList) { + ret = ERROR_NOT_ENOUGH_MEMORY; + } else { + GroupBuffer = GroupList->GroupBuffer; + + for (i = 0; i < Entries; i++) { + CurrentLine = map_LineNext(hMap); + + if (CurrentLine != NULL) { + map_ParseGroup(CurrentLine->Line, Name, NewName); + + if (lstrlen(Name)) { + lstrcpy(GroupBuffer[ActualEntries].Name, Name); + lstrcpy(GroupBuffer[ActualEntries].NewName, NewName); + + if (lstrcmpi(Name, NewName)) + GroupBuffer[ActualEntries].IsNewName = TRUE; + + ActualEntries++; + } + } + } + + if (ActualEntries != Entries) + GroupList = (GROUP_LIST *) ReallocMemory((HGLOBAL) GroupList, sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER)* ActualEntries)); + + if (GroupList == NULL) + ret = ERROR_NOT_ENOUGH_MEMORY; + else + GroupList->Count = ActualEntries; + + *lpGroups = GroupList; + } + + return ret; +} // map_GroupsEnum + + +/*+-------------------------------------------------------------------------+ + | MapFileWrite() + | + +-------------------------------------------------------------------------+*/ +BOOL MapFileWrite(HANDLE hFile, LPTSTR String) { + DWORD wrote; + static char tmpStr[MAX_LINE_LEN + 1]; + + WideCharToMultiByte(CP_ACP, 0, String, -1, tmpStr, sizeof(tmpStr), NULL, NULL); + + if (!WriteFile(hFile, tmpStr, strlen(tmpStr), &wrote, NULL)) + return FALSE; + + return TRUE; +} // MapFileWrite + + +/*+-------------------------------------------------------------------------+ + | MapFileOpen() + | + +-------------------------------------------------------------------------+*/ +HANDLE MapFileOpen(LPTSTR FileNameW) { + int ret; + HANDLE hFile = NULL; + char FileName[MAX_PATH + 1]; + + WideCharToMultiByte(CP_ACP, 0, FileNameW, -1, FileName, sizeof(FileName), NULL, NULL); + + DeleteFile(FileNameW); + + // Now do the actual creation with error handling... + do { + ret = IDOK; + hFile = CreateFileA( FileName, GENERIC_WRITE, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile == INVALID_HANDLE_VALUE) + ret = ErrorBoxRetry(Lids(IDS_MAPCREATEFAIL)); + + } while(ret == IDRETRY); + + return(hFile); + +} // MapFileOpen + + + +/*+-------------------------------------------------------------------------+ + | MappingFileCreate() + | + | Creates a mapping file. This allows the admin to specify for each + | user a new username and password. + | + +-------------------------------------------------------------------------+*/ +BOOL MappingFileCreate(LPTSTR FileName, LPTSTR Server) { + BOOL status = FALSE; + DWORD ret = 0; + USER_LIST *Users; + DWORD UserCount; + GROUP_LIST *Groups; + GROUP_BUFFER *GroupBuffer; + USER_BUFFER *UserBuffer; + DWORD GroupCount; + int Count; + HANDLE hFile = NULL; + static TCHAR tmpStr[MAX_LINE_LEN + 1]; + static TCHAR tmpStr2[MAX_LINE_LEN + 1]; + + // Create Empty map file + hFile = MapFileOpen(FileName); + if (hFile == INVALID_HANDLE_VALUE) + return FALSE; + + CursorHourGlass(); + + // Now write out header gunk + status = MapFileWrite(hFile, Lids(IDS_LINE)); + wsprintf(tmpStr, Lids(IDS_M_1), Server); + wsprintf(tmpStr2, Lids(IDS_BRACE), tmpStr); + if (status) + status = MapFileWrite(hFile, tmpStr2); + + wsprintf(tmpStr, Lids(IDS_BRACE), Lids(IDS_M_2)); + if (status) + status = MapFileWrite(hFile, tmpStr); + + wsprintf(tmpStr, Lids(IDS_BRACE), TEXT("")); + if (status) + status = MapFileWrite(hFile, tmpStr); + + wsprintf(tmpStr, Lids(IDS_BRACE), Lids(IDS_M_3)); + if (status) + status = MapFileWrite(hFile, tmpStr); + + wsprintf(tmpStr, Lids(IDS_BRACE), Lids(IDS_M_4)); + if (status) + status = MapFileWrite(hFile, tmpStr); + + wsprintf(tmpStr, Lids(IDS_BRACE), TEXT("")); + if (status) + status = MapFileWrite(hFile, tmpStr); + + if (status) + status = MapFileWrite(hFile, Lids(IDS_LINE)); + + // [USERS] section header + if (DoUsers && status) + status = MapFileWrite(hFile, Lids(IDS_M_5)); + + // If anything went wrong with writing header, get out + if (!status) { + CursorNormal(); + return FALSE; + } + + // Header is all done - now lets do the actual users and such + if (!(ret = NWServerSet(Server))) { + // + // If users were selected then put them into the map file + // + if (DoUsers) { + if (!NWUsersEnum(&Users, FALSE) && (Users != NULL)) { + UserCount = Users->Count; + UserBuffer = Users->UserBuffer; + + for (Count = 0; Count < (int) UserCount; Count++) { + if (status) { + switch(PasswordOption) { + case 0: // No password + wsprintf(tmpStr, TEXT("%s, %s,\r\n"), UserBuffer[Count].Name, UserBuffer[Count].Name); + break; + + case 1: // Password is username + wsprintf(tmpStr, TEXT("%s, %s, %s\r\n"), UserBuffer[Count].Name, UserBuffer[Count].Name, UserBuffer[Count].Name); + break; + + case 2: // Password is constant + wsprintf(tmpStr, TEXT("%s, %s, %s\r\n"), UserBuffer[Count].Name, UserBuffer[Count].Name, PasswordConstant); + break; + } + status = MapFileWrite(hFile, tmpStr); + } + } + + FreeMemory((LPBYTE) Users); + } + } + + // + // If groups were selected then put them in map file + // + if (DoGroups) { + // [GROUPS] section header + if (status) + status = MapFileWrite(hFile, Lids(IDS_M_6)); + + if (!NWGroupsEnum(&Groups, FALSE) && (Groups != NULL)) { + GroupCount = Groups->Count; + GroupBuffer = Groups->GroupBuffer; + + for (Count = 0; Count < (int) GroupCount; Count++) { + if (status) { + wsprintf(tmpStr, TEXT("%s, %s\r\n"), GroupBuffer[Count].Name, GroupBuffer[Count].Name); + status = MapFileWrite(hFile, tmpStr); + } + } + + FreeMemory((LPBYTE) Groups); + } + + } + + NWServerFree(); + } + + CloseHandle( hFile ); + CursorNormal(); + return status; + +} // MappingFileCreate + + +/*+-------------------------------------------------------------------------+ + | MappingFileNameResolve() + | + +-------------------------------------------------------------------------+*/ +BOOL MappingFileNameResolve(HWND hDlg) { + HWND hCtrl; + static char FileNameA[MAX_PATH + 1]; + static char CmdLine[MAX_PATH + 1 + 12]; // Editor + file + TCHAR drive[MAX_DRIVE + 1]; + TCHAR dir[MAX_PATH + 1]; + TCHAR fname[MAX_PATH + 1]; + TCHAR ext[_MAX_EXT + 1]; + UINT uReturn; + BOOL ret = TRUE; + + // First check filename + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + * (WORD *)MappingFile = sizeof(MappingFile); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) MappingFile); + lsplitpath(MappingFile, drive, dir, fname, ext); + + // remake path so it is fully qualified + if ((drive[0] == TEXT('\0')) && (dir[0] == TEXT('\0'))) + lstrcpy(dir, ProgPath); + + if (ext[0] == TEXT('\0')) + lstrcpy(ext, Lids(IDS_S_36)); + + lmakepath(MappingFile, drive, dir, fname, ext); + + if (MappingFileCreate(MappingFile, SourceServ)) { + if (MessageBox(hDlg, Lids(IDS_MAPCREATED), Lids(IDS_APPNAME), MB_YESNO | MB_ICONQUESTION) == IDYES) { + + WideCharToMultiByte(CP_ACP, 0, MappingFile, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + + wsprintfA(CmdLine, "Notepad %s", FileNameA); + uReturn = WinExec(CmdLine, SW_SHOW); + } + } else { + MessageBox(hDlg, Lids(IDS_MAPCREATEFAIL), Lids(IDS_TXTWARNING), MB_OK); + ret = FALSE; + } + + return ret; + +} // MappingFileNameResolve + + +/*+-------------------------------------------------------------------------+ + | MapCreate() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK MapCreateProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + int wmId, wmEvent; + static short UserNameTab, GroupNameTab, PasswordsTab, DefaultsTab; + + switch (message) { + + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // limit edit field lengths + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PATH, 0); + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PW_LEN, 0); + + // set mapping file name and init OK button appropriatly + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) MappingFile); + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) { + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, TRUE); + } else { + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, FALSE); + } + + // check Users and Groups checkbox's + hCtrl = GetDlgItem(hDlg, IDC_USERS); + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + hCtrl = GetDlgItem(hDlg, IDC_GROUPS); + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1); + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + // [OK] button + case IDOK: + // Figure out what password option is checked... + hCtrl = GetDlgItem(hDlg, IDC_RADIO1); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + PasswordOption = 0; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO2); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + PasswordOption = 1; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO3); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + PasswordOption = 2; + + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + * (WORD *)PasswordConstant = sizeof(PasswordConstant); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) PasswordConstant); + + EnableWindow(hDlg, FALSE); + MappingFileNameResolve(hDlg); + EnableWindow(hDlg, TRUE); + EndDialog(hDlg, 0); + return (TRUE); + break; + + // [CANCEL] button + case IDCANCEL: + EndDialog(hDlg, 0); + return (TRUE); + break; + + // [HELP] button + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_CMAP); + return (TRUE); + break; + + // Checkbox for Users + case IDC_USERS: + DoUsers = !DoUsers; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO1); + EnableWindow(hCtrl, DoUsers); + hCtrl = GetDlgItem(hDlg, IDC_RADIO2); + EnableWindow(hCtrl, DoUsers); + hCtrl = GetDlgItem(hDlg, IDC_RADIO3); + EnableWindow(hCtrl, DoUsers); + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + EnableWindow(hCtrl, DoUsers); + + return (TRUE); + break; + + // Checkbox for Groups + case IDC_GROUPS: + DoGroups = !DoGroups; + return (TRUE); + break; + + // Edit field for password constant + case IDC_PWCONST: + + if (wmEvent == EN_CHANGE) + CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO3); + + break; + + // Edit field for password constant + case IDC_MAPPINGFILE: + if (wmEvent == EN_CHANGE) { + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) { + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, TRUE); + } else { + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, FALSE); + } + + } + break; + + // [...] button for mapping file + case IDC_BTNMAPPINGFILE: + // Let the user browse for a file + if (!UserFileGet(hDlg, MappingFile)) { + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) MappingFile); + SetFocus(hCtrl); + } + return (TRUE); + break; + + } + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // MapCreateProc + + + +/*+-------------------------------------------------------------------------+ + | MapFileCreate() + | + +-------------------------------------------------------------------------+*/ +BOOL MapFileCreate(HWND hDlg, LPTSTR FileName, LPTSTR Server) { + DLGPROC lpfnDlg; + + DoUsers = TRUE; + DoGroups = TRUE; + PasswordOption = 0; + lstrcpy(MappingFile, FileName); + lstrcpy(PasswordConstant, TEXT("")); + SourceServ = Server; + + lpfnDlg = MakeProcInstance((DLGPROC)MapCreateProc, hInst); + DialogBox(hInst, TEXT("MAPCreate"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + + lstrcpy(FileName, MappingFile); + return TRUE; +} // MapFileCreate + + diff --git a/private/nw/convert/nwconv/map.h b/private/nw/convert/nwconv/map.h new file mode 100644 index 000000000..58007d7d8 --- /dev/null +++ b/private/nw/convert/nwconv/map.h @@ -0,0 +1,62 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HMAPFILE_ +#define _HMAPFILE_ + +#ifdef __cplusplus +extern "C"{ +#endif + + +typedef struct _MAP_LINE { + struct _MAP_LINE *next; + struct _MAP_LINE *prev; + + LPTSTR Line; +} MAP_LINE; + +typedef struct _MAP_SECTION { + struct _MAP_SECTION *next; + struct _MAP_SECTION *prev; + + LPTSTR Name; + MAP_LINE *FirstLine; + MAP_LINE *LastLine; + ULONG LineCount; +} MAP_SECTION; + +typedef struct _MAP_FILE { + HANDLE hf; + BOOL Modified; + + MAP_SECTION *FirstSection; + MAP_SECTION *LastSection; + MAP_SECTION *CurrentSection; + MAP_LINE *CurrentLine; + ULONG SectionCount; + TCHAR Name[]; +} MAP_FILE; + +#define FILE_CACHE_SIZE 2048 +#define MAX_LINE_LEN 512 + +#define SECTION_BEGIN_CHAR '[' +#define SECTION_END_CHAR ']' +#define COMMENT_CHAR ';' +#define WORD_DELIMITER ',' + +BOOL MapFileCreate(HWND hDlg, LPTSTR FileName, LPTSTR Server); +DWORD map_UsersEnum(MAP_FILE *hMap, USER_LIST **lpUsers); +DWORD map_GroupsEnum(MAP_FILE *hMap, GROUP_LIST **lpGroups); + +MAP_FILE *map_Open(TCHAR *FileName); +void map_Close(MAP_FILE *hMap); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/private/nw/convert/nwconv/mem.c b/private/nw/convert/nwconv/mem.c new file mode 100644 index 000000000..2d499c0ed --- /dev/null +++ b/private/nw/convert/nwconv/mem.c @@ -0,0 +1,381 @@ +//============================================================================= +// Microsoft (R) Bloodhound (tm). Copyright (C) 1991-1992. +// +// MODULE: mem.c +// +// Modification History +// +// raypa 01/28/93 Created +// stevehi 07/21/93 Added memory checking functionality +// raypa 07/21/93 Changed to use LPTR rather than LocalLock. +// Tom Laird-McConnell 08/16/93 Changed to fix no size info in functions +// arth 06/16/94 Added extra debug tracing code +//============================================================================= + +#include "switches.h" + +#include +#include "mem.h" +#include +#include +#include "debug.h" +#include "strings.h" +#include +#include "utils.h" + +#ifdef DEBUG_MEM +BOOL _rtlpheapvalidateoncall = TRUE; + +typedef struct _MEM_BUFFER { + struct _MEM_BUFFER *Next; + struct _MEM_BUFFER *Prev; + ULONG Size; + +} MEM_BUFFER; + +MEM_BUFFER *MemList = NULL; +ULONG AllocCount = 0; +#endif + +//============================================================================= +// Define Tags used by the following routines to stick into memory +// and compare later. +//============================================================================= + +#define AllocTagTakeStart 0x3e4b4154 //... TAK> +#define AllocTagTakeStop 0x4b41543c //... +#define AllocTagReAllocStop 0x4145523c //... +#define AllocTagFreeStop 0x4552463c //... Size; + + lpByte = (LPBYTE) lpMem; + lpByte -= sizeof(DWORD); + + dprintf(TEXT("%lu %lX) Alloc Size: %lu\n"), i++, lpMem, lpMem->Size); + + if ( *(LPDWORD)(lpByte) != AllocTagTakeStart ) { + dprintf(TEXT("AllocTagStart Corrupt\n")); + dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize); + DebugBreak; + } + + lpByte += sizeof(DWORD) + sizeof(MEM_BUFFER) + lpMem->Size; + if ( *(LPDWORD)(lpByte) != AllocTagTakeStop ) { + dprintf(TEXT("AllocTagStop Corrupt\n")); + dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize); + DebugBreak; + } + + lpMem = lpMem->Next; + } + + dprintf(TEXT("\nTotal Alloc Mem: %lu\n"), TotSize); +} // DBG_MemEnum + +#endif + + +//============================================================================= +// FUNCTION: AllocMemory() +// +// Modification History +// +// raypa 01/28/93 Created. +// stevehi 07/21/93 Added memory checking functionality +// raypa 07/21/93 Changed to use LPTR rather than LocalLock. +// raypa 07/21/93 Return NULL if size is zero. +//============================================================================= + +LPVOID WINAPI AllocMemory(DWORD size) { + register LPBYTE lpByte; + int ret; + +#ifndef DEBUG_MEM + do { + ret = IDOK; + lpByte = LocalAlloc(LPTR, size); + + if ((lpByte == NULL) && (size != 0)) { + MessageBeep(MB_ICONHAND); + ret = MessageBox(NULL, Lids(IDS_S_7), Lids(IDS_S_8), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL); + + if (ret == IDCANCEL) + exit(1); + } + + } while (ret == IDRETRY); + + return (LPVOID) lpByte; +#else + DWORD ActualSize; + MEM_BUFFER *lpMem; + + if ( size != 0 ) { + do { + ret = IDOK; + // take into account 2 tags and buffer header + lpByte = LocalAlloc(LPTR, size + (2 * sizeof(DWORD)) + sizeof(MEM_BUFFER)); + + if (lpByte == NULL) { + MessageBeep(MB_ICONHAND); + DBG_MemEnum(); + ret = MessageBox(NULL, TEXT("Out of Memory"), TEXT("NwConv - Error"), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL); + + if (ret == IDCANCEL) + exit(1); + } + + } while (ret == IDRETRY); + + AllocCount++; + ActualSize = LocalSize(lpByte) - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER); + *((LPDWORD)(lpByte)) = AllocTagTakeStart; + lpMem = (MEM_BUFFER *) &lpByte[sizeof(DWORD)]; + + lpMem->Next = MemList; + lpMem->Prev = NULL; + if (MemList != NULL) + MemList->Prev = lpMem; + + lpMem->Size = ActualSize; + MemList = lpMem; + + *((LPDWORD)(lpByte + ActualSize + sizeof(DWORD) + sizeof(MEM_BUFFER))) = AllocTagTakeStop; + + return (LPVOID) &lpByte[sizeof(DWORD) + sizeof(MEM_BUFFER)]; + } + + return NULL; +#endif + +} // AllocMemory + + +//============================================================================= +// FUNCTION: ReallocMemory() +// +// Modification History +// +// raypa 01/28/93 Created. +// stevehi 07/21/93 Added memory checking functionality +// raypa 07/21/93 Changed to use LPTR rather than LocalLock. +// raypa 10/22/93 If the ptr is NULL then use AllocMemory. +//============================================================================= + +LPVOID WINAPI ReallocMemory(LPVOID ptr, DWORD NewSize) { +#ifdef DEBUG_MEM + DWORD GSize; + MEM_BUFFER *lpMem; + MEM_BUFFER *OldMem; +#endif + + //========================================================================= + // If the ptr is NULL then use AllocMemory. + //========================================================================= + + if ( ptr == NULL ) { + return AllocMemory(NewSize); + } + +#ifndef DEBUG_MEM + return LocalReAlloc(ptr, NewSize, LHND); +#else + // we are reallocing... might as well check the tags here... + + (LPBYTE)ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); + + GSize = LocalSize (ptr); + + if ( *(LPDWORD)(ptr) != AllocTagTakeStart ) + DebugBreak; + + // get the size and check the end tag + + if (GSize && ( *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD))) != AllocTagTakeStop ) { + DebugBreak; + } + + // just for grins, mark the realloc part. + + *(LPDWORD)(ptr) = AllocTagReAllocStart; + + if ( GSize ) + *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD) ) = AllocTagReAllocStop; + + OldMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); + + ptr = LocalReAlloc(ptr, NewSize + sizeof(MEM_BUFFER) + (2 * sizeof(DWORD)), LHND); + + if (ptr == NULL ) { + dprintf(TEXT("NWConv - Local Realloc failed with %ld.\r\n"), GetLastError() ); + + DebugBreak; + + return NULL; + } + + lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); + + if (MemList == OldMem) + MemList = lpMem; + + if (lpMem->Prev != NULL) + lpMem->Prev->Next = lpMem; + + if (lpMem->Next != NULL) + lpMem->Next->Prev = lpMem; + + lpMem->Size = NewSize; + + *((LPDWORD)ptr) = AllocTagTakeStart; + *((LPDWORD)((LPBYTE)ptr + NewSize + sizeof(MEM_BUFFER) + sizeof(DWORD))) = AllocTagTakeStop; + + return (LPVOID)((LPBYTE)ptr + sizeof(DWORD) + sizeof(MEM_BUFFER)); +#endif +} // ReAllocMemory + + +//============================================================================= +// FUNCTION: FreeMemory() +// +// Modification History +// +// raypa 01/28/93 Created. +// stevehi 07/21/93 Added memory checking functionality +// raypa 07/21/93 Changed to use LPTR rather than LocalLock. +// raypa 07/21/93 Fixed GP-fault on NULL ptr. +// raypa 11/21/93 Allow freeing of NULL pointer. +//============================================================================= + +VOID WINAPI FreeMemory(LPBYTE ptr) { + //========================================================================= + // If the pointer is NULL, exit. + //========================================================================= + + if ( ptr != NULL ) { +#ifdef DEBUG_MEM + register DWORD Size; + register LPDWORD DwordPtr; + MEM_BUFFER *lpMem; + + ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); + lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); + + Size = LocalSize(ptr); + + //... Check start tag + DwordPtr = (LPDWORD) &ptr[0]; + + if ( *DwordPtr != AllocTagTakeStart ) { + dprintf(TEXT("NWConv - FreeMemory: Invalid start signature: ptr = %X\r\n"), ptr); + + DebugBreak(); + } + else { + *DwordPtr = AllocTagFreeStart; + } + + //... get the size and check the end tag + + DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)]; + + if ( *DwordPtr != AllocTagTakeStop ) { + dprintf(TEXT("NWConv - FreeMemory: Invalid end signature: ptr = %X\r\n"), ptr); + + DebugBreak(); + } + else { + *DwordPtr = AllocTagFreeStop; + } + + AllocCount--; + if (MemList == lpMem) + MemList = lpMem->Next; + + if (lpMem->Prev != NULL) + lpMem->Prev->Next = lpMem->Next; + + if (lpMem->Next != NULL) + lpMem->Next->Prev = lpMem->Prev; +#endif + + LocalFree(ptr); + } +} // FreeMemory + + +//============================================================================= +// FUNCTION: MemorySize() +// +// Modification History +// +// Tom Laird-McConnell 08/02/93 Created. +// Tom Laird-McConnell 08/02/93 Changed to use local var for size... +//============================================================================= + +DWORD WINAPI MemorySize(LPBYTE ptr) { +#ifdef DEBUG_MEM + register DWORD Size; + + if ( ptr != NULL ) { + register LPDWORD DwordPtr; + + ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); + + Size = LocalSize(ptr); + + DwordPtr = (LPDWORD) &ptr[0]; + + // Check start tag + + if ( *DwordPtr != AllocTagTakeStart ) { + dprintf(TEXT("NWConv - MemorySize: Invalid start signature!\r\n")); + + DebugBreak; + } + + // get the size and check the end tag + + DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)]; + + if ( *DwordPtr != AllocTagTakeStop ) { + dprintf(TEXT("NWConv - MemorySize: Invalid end signature!\r\n")); + + DebugBreak; + } + + return (Size - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER)); + } +#endif + + return LocalSize(ptr); +} // MemorySize + + diff --git a/private/nw/convert/nwconv/mem.h b/private/nw/convert/nwconv/mem.h new file mode 100644 index 000000000..f3c5cf329 --- /dev/null +++ b/private/nw/convert/nwconv/mem.h @@ -0,0 +1,40 @@ +//============================================================================= +// Microsoft (R) Bloodhound (tm). Copyright (C) 1991-1993. +// +// MODULE: objmgr.h +// +// Modification History +// +// raypa 03/17/93 Created. +//============================================================================= + +#if !defined(_OBJMGR_) + + +#define _OBJMGR_ +#pragma pack(1) + +#ifdef __cplusplus +extern "C"{ +#endif + +//============================================================================= +// Memory functions. +//============================================================================= + +extern LPVOID WINAPI AllocMemory(DWORD size); + +extern LPVOID WINAPI ReallocMemory(LPVOID ptr, DWORD NewSize); + +extern VOID WINAPI FreeMemory(LPVOID ptr); + +extern DWORD WINAPI MemorySize(LPVOID ptr); + +void MemInit(); + +#ifdef __cplusplus +} +#endif + +#pragma pack() +#endif diff --git a/private/nw/convert/nwconv/moveit.ico b/private/nw/convert/nwconv/moveit.ico new file mode 100644 index 000000000..44d2cb60c Binary files /dev/null and b/private/nw/convert/nwconv/moveit.ico differ diff --git a/private/nw/convert/nwconv/netutil.c b/private/nw/convert/nwconv/netutil.c new file mode 100644 index 000000000..7a99ba6b9 --- /dev/null +++ b/private/nw/convert/nwconv/netutil.c @@ -0,0 +1,437 @@ +/* + +-------------------------------------------------------------------------+ + | Network Utility Functions | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [NetUtil.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 16, 1993] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Jun 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "globals.h" +#include "netutil.h" + +static LPTSTR ServName; +static TCHAR szPassword[PWLEN+1]; +static TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + +LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL BadPassword; + +/*+-------------------------------------------------------------------------+ + | FixPathSlash() + | + +-------------------------------------------------------------------------+*/ +void FixPathSlash(LPTSTR NewPath, LPTSTR Path) { + UINT PathLen; + lstrcpy(NewPath, Path); + + PathLen = lstrlen(Path); + // If ending character is not a slash then put one on + if (PathLen && (Path[PathLen - 1] != '\\')) + lstrcat(NewPath, TEXT("\\")); + +} // FixPathSlash + + +/*+-------------------------------------------------------------------------+ + | ShareNameParse() + | + +-------------------------------------------------------------------------+*/ +LPTSTR ShareNameParse(LPTSTR ShareName) { + ULONG i; + + i = lstrlen(ShareName); + if (!i) + return ShareName; + + // Scan backwards for first slash + i--; + while (i && ShareName[i] != TEXT('\\')) + i--; + + // if found slash then increment past it + if (i) + i++; + + return &ShareName[i]; + +} // ShareNameParse + + +static LPTSTR LocName = NULL; +/*+-------------------------------------------------------------------------+ + | GetLocalName() + | + +-------------------------------------------------------------------------+*/ +void GetLocalName(LPTSTR *lpLocalName) { + int size; + + if (LocName != NULL) { + *lpLocalName = LocName; + } else { + LocName = AllocMemory((MAX_COMPUTERNAME_LENGTH + 1) * sizeof(TCHAR)); + size = MAX_COMPUTERNAME_LENGTH + 1; + + if (LocName) { + GetComputerName(LocName, &size); + *lpLocalName = LocName; + } else + *lpLocalName = NULL; + } + +} // GetLocalName + + +/*+-------------------------------------------------------------------------+ + | SetProvider() + | + +-------------------------------------------------------------------------+*/ +BOOL SetProvider(LPTSTR Provider, NETRESOURCE *ResourceBuf) { + ResourceBuf->dwScope = RESOURCE_GLOBALNET; + ResourceBuf->dwType = RESOURCETYPE_DISK; + ResourceBuf->dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC; + + // Don't take the frigging _RESERVED flag out - it isn't documented except in the include + // file and it crashes without it! + ResourceBuf->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED; + + ResourceBuf->lpLocalName = NULL; + ResourceBuf->lpRemoteName = Provider; + ResourceBuf->lpComment = NULL; + ResourceBuf->lpProvider = Provider; + return TRUE; + +} // SetProvider + + +/*+-------------------------------------------------------------------------+ + | AllocEnumBuffer() + | + +-------------------------------------------------------------------------+*/ +ENUM_REC *AllocEnumBuffer() { + ENUM_REC *Buf; + + Buf = (ENUM_REC *) AllocMemory(sizeof(ENUM_REC)); + + if (Buf) { + // Init the record + Buf->next = NULL; + Buf->cEntries = 0; + Buf->cbBuffer = 0; + Buf->lpnr = NULL; + } + + return Buf; + +} // AllocEnumBuffer + + + +/*+-------------------------------------------------------------------------+ + | EnumBufferBuild() + | + | Uses WNetEnum to enumerate the resource. WNetEnum is really brain- + | dead so we need to create a temporary holding array and then build + | up a finalized complete buffer in the end. A linked list of inter- + | mediate buffer records is created first. + | + +-------------------------------------------------------------------------+*/ +DWORD FAR PASCAL EnumBufferBuild(ENUM_REC **BufHead, int *NumBufs, NETRESOURCE ResourceBuf) { + DWORD status = ERROR_NO_NETWORK; + ENUM_REC *CurrBuf; + DWORD dwResultEnum; + HANDLE hEnum = NULL; + DWORD cbBuffer = 16384; // 16K default buffer size. + DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries + ENUM_REC **lppEnumRec; + LPNETRESOURCE lpnrLocal; + + status = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, &ResourceBuf, &hEnum); + + if (status == NO_ERROR) { + + *BufHead = NULL; + lppEnumRec = BufHead; + + do { + + cbBuffer = 16384; // 16K default buffer size + cEntries = 0xFFFFFFFF; // enumerate all possible entries + + // Allocate memory for NETRESOURCE structures. + lpnrLocal = (LPNETRESOURCE) AllocMemory(cbBuffer); + + if (lpnrLocal == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + dwResultEnum = WNetEnumResource(hEnum, &cEntries, (LPVOID) lpnrLocal, &cbBuffer); + + if (dwResultEnum == NO_ERROR) { + // Create a new Enum rec and link it to the chain + *lppEnumRec = AllocEnumBuffer(); + + if (*lppEnumRec == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + CurrBuf = *lppEnumRec; + + // Init for next loop through buffer + lppEnumRec = &CurrBuf->next; + + // Put enumeration buffer in our Enum rec. + CurrBuf->lpnr = lpnrLocal; + CurrBuf->cEntries = cEntries; + CurrBuf->cbBuffer = cbBuffer; + (*NumBufs)++; + + } else { // Since this is not assigned in a rec we need to free it here. + FreeMemory((HGLOBAL) lpnrLocal); + + if (dwResultEnum != ERROR_NO_MORE_ITEMS) { + status = dwResultEnum; + break; + } + } + + } while (dwResultEnum != ERROR_NO_MORE_ITEMS); + + status = WNetCloseEnum(hEnum); + + } + + return status; + +} // EnumBufferBuild + + +/*+-------------------------------------------------------------------------+ + | UseAddPswd() + | + | Attempts to make connections to \\szServer\admin$, asking for + | passwords if necessary. + | + | Returns TRUE if use was added, + | FALSE otherwise + | + +-------------------------------------------------------------------------+*/ +BOOL UseAddPswd(HWND hwnd, LPTSTR UserName, LPTSTR lpszServer, LPTSTR lpszShare, LPTSTR Provider) { + WORD nState; + WORD fCancel; + DLGPROC lpProc; + NETRESOURCE nr; + NET_API_STATUS retcode; + LPTSTR lpPassword; + static TCHAR szTmp[MAX_UNC_PATH+1]; + + ServName = lpszServer; + + nr.dwScope = 0; + nr.dwType = RESOURCETYPE_DISK; + nr.dwDisplayType = 0; + nr.dwUsage = 0; + nr.lpProvider = NULL; + + nState = 1; // try default password + lpPassword = NULL; + BadPassword = FALSE; + lstrcpy(szUserName, UserName); + + for(;;) { + // Concatenate server and share + wsprintf(szTmp, TEXT("%s\\%s"), lpszServer, lpszShare); + + // Fill in data structure + nr.lpLocalName = NULL; + nr.lpRemoteName = szTmp; + nr.lpProvider = Provider; + + // Try to make the connection + if (lstrlen(szUserName)) + retcode = WNetAddConnection2(&nr, lpPassword, szUserName, 0); + else + retcode = WNetAddConnection2(&nr, lpPassword, NULL, 0); + + switch(retcode) { + case NERR_Success: + lstrcpy(UserName, szUserName); + return TRUE; + + case ERROR_INVALID_PASSWORD: + BadPassword = TRUE; + break; + + case ERROR_ACCESS_DENIED: + case ERROR_NETWORK_ACCESS_DENIED: + case ERROR_SESSION_CREDENTIAL_CONFLICT: + case ERROR_NO_SUCH_USER: + case ERROR_NO_MORE_ITEMS: + case ERROR_LOGON_FAILURE: + BadPassword = FALSE; + break; + + case ERROR_BAD_NETPATH: + case ERROR_BAD_NET_NAME: + + default: + return FALSE; + } + + // Get new password from user + lpProc = MakeProcInstance(PasswordDlgProc, hInst); + fCancel = !DialogBoxParam(hInst, TEXT("PasswordEnter"), hwnd, lpProc, 0); + + // Gamble call only once + FreeProcInstance(lpProc); + + // Save... + if(!fCancel) { + if(nState) { + nState = 2; // try specified password + lpPassword = szPassword; + } else { + nState = 1; // try default password + lpPassword = NULL; + } + } else { + SetLastError(ERROR_SUCCESS); // just aborting... + return FALSE; + } + } + +} // UseAddPswd + + +/*+-------------------------------------------------------------------------+ + | PasswordDlgProc() + | + | Gets a password from the user and copies it into the string pointed + | to by lParam. This string must have room for at least (PWLEN + 1) + | characters. Returns TRUE if OK is pressed, or FALSE if Cancel + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch (msg) { + case WM_INITDIALOG: + CursorNormal(); + + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + SetDlgItemText(hDlg, IDC_SERVNAME, ServName); + SendDlgItemMessage(hDlg, IDC_PASSWORD, EM_LIMITTEXT, PWLEN, 0L); + SendDlgItemMessage(hDlg, IDC_USERNAME, EM_LIMITTEXT, MAX_USER_NAME_LEN, 0L); + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + break; + + case WM_COMMAND: + switch(wParam) { + case IDOK: + CursorHourGlass(); + GetDlgItemText(hDlg, IDC_PASSWORD, szPassword, PWLEN+1); + GetDlgItemText(hDlg, IDC_USERNAME, szUserName, MAX_USER_NAME_LEN+1); + + EndDialog(hDlg, TRUE); + break; + + case IDCANCEL: + CursorHourGlass(); + EndDialog(hDlg, FALSE); + break; + + case ID_INIT: + SendDlgItemMessage(hDlg, IDC_USERNAME, WM_SETTEXT, 0, (LPARAM) szUserName); + + if (BadPassword) + SetFocus(GetDlgItem(hDlg, IDC_PASSWORD)); + else { + SetFocus(GetDlgItem(hDlg, IDC_USERNAME)); + SendDlgItemMessage(hDlg, IDC_USERNAME, EM_SETSEL, 0, (LPARAM) MAKELPARAM(0, -1) ); + } + + break; + + default: + return FALSE; + } + break; + + default: + return FALSE; + } + return TRUE; + +} // PasswordDlgProc + + +/*+-------------------------------------------------------------------------+ + | NicePath() + | + +-------------------------------------------------------------------------+*/ +LPTSTR NicePath(int Len, LPTSTR Path) { + static TCHAR NewPath[MAX_PATH + 80]; + int eptr, fptr; + + // If the path fits then just return it + if (lstrlen(Path) <= Len) { + lstrcpy(NewPath, Path); + return NewPath; + } + + // The path doesn't fit, so need to reduce it down in size - to do this first try + // to get the last part of the path looking for slash that starts it. + eptr = fptr = 0; + while (Path[eptr] != TEXT('\0')) + eptr++; + + // back up before ending NULL also before any ending slash + eptr--; + while ((Path[eptr] == TEXT('\\')) && eptr > 0) + eptr--; + + // now try to find beginning slash + while ((Path[eptr] != TEXT('\\')) && eptr > 0) + eptr--; + + // if at beginning of string then is just one name so copy all of it we can + if (eptr == 0) { + lstrcpyn(NewPath, Path, Len); + return NewPath; + } + + // check if the name after the last slash can all fit - also take into account + // the "..." we are going to tack into the name + fptr = lstrlen(Path) - eptr; + fptr += 4; + if (fptr >= Len) { + lstrcpyn(NewPath, &Path[eptr], Len); + return NewPath; + } + + // We need to create a path shortening to the desired length by removing the mid + // part of the path and replacing it with "..." + fptr = Len - fptr; + lstrcpyn(NewPath, Path, fptr); + lstrcat(NewPath, TEXT("...")); + lstrcat(NewPath, &Path[eptr]); + return NewPath; + +} // NicePath diff --git a/private/nw/convert/nwconv/netutil.h b/private/nw/convert/nwconv/netutil.h new file mode 100644 index 000000000..f2402d759 --- /dev/null +++ b/private/nw/convert/nwconv/netutil.h @@ -0,0 +1,87 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HNETUTIL_ +#define _HNETUTIL_ + +#ifdef __cplusplus +extern "C"{ +#endif + +// made to match usri3 info structure for easy save/retrieval +typedef struct _NT_USER_INFO { + LPWSTR name; + LPWSTR password; + DWORD password_age; + DWORD priv; + LPWSTR home_dir; + LPWSTR comment; + DWORD flags; + LPWSTR script_path; + DWORD auth_flags; + LPWSTR full_name; + LPWSTR usr_comment; + LPWSTR parms; + LPWSTR workstations; + DWORD last_logon; + DWORD last_logoff; + DWORD acct_expires; + DWORD max_storage; + DWORD units_per_week; + PBYTE logon_hours; + DWORD bad_pw_count; + DWORD num_logons; + LPWSTR logon_server; + DWORD country_code; + DWORD code_page; + DWORD user_id; + DWORD primary_group_id; + LPWSTR profile; + LPWSTR home_dir_drive; + DWORD password_expired; +} NT_USER_INFO, *PNT_USER_INFO, *LPNT_USER_INFO; + + +typedef struct _FPNW_INFO { + WORD MaxConnections; + WORD PasswordInterval; + BYTE GraceLoginAllowed; + BYTE GraceLoginRemaining; + LPWSTR LoginFrom; + LPWSTR HomeDir; +} FPNW_INFO, *PFPNW_INFO, *LPFPNW_INFO; + + + +// made to match USER_MODALS_INFO_0 info structure for easy save/retrieval +typedef struct _NT_DEFAULTS { + DWORD min_passwd_len; + DWORD max_passwd_age; + DWORD min_passwd_age; + DWORD force_logoff; + DWORD password_hist_len; +} NT_DEFAULTS, *PNT_DEFAULTS, *LPNT_DEFAULTS; + + +typedef struct _EnumRec { + struct _EnumRec *next; + DWORD cEntries; + DWORD cbBuffer; + LPNETRESOURCE lpnr; +} ENUM_REC; + +void FixPathSlash(LPTSTR NewPath, LPTSTR Path); +LPTSTR ShareNameParse(LPTSTR ShareName); +void GetLocalName(LPTSTR *lpLocalName); +BOOL SetProvider(LPTSTR Provider, NETRESOURCE *ResourceBuf); +ENUM_REC *AllocEnumBuffer(); +DWORD FAR PASCAL EnumBufferBuild(ENUM_REC **BufHead, int *NumBufs, NETRESOURCE ResourceBuf); +BOOL UseAddPswd(HWND hwnd, LPTSTR UserName, LPTSTR lpszServer, LPTSTR lpszShare, LPTSTR Provider); +LPTSTR NicePath(int Len, LPTSTR Path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/ntnetapi.c b/private/nw/convert/nwconv/ntnetapi.c new file mode 100644 index 000000000..a363bf99d --- /dev/null +++ b/private/nw/convert/nwconv/ntnetapi.c @@ -0,0 +1,3644 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + NTNetaAPI.c + +Abstract: + + +Author: + + Arthur Hanson (arth) 16-Jun-1994 + +Revision History: + +--*/ + + +#include "globals.h" + +#include +#include +#include +#include + +#include +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "loghours.h" +#include "usrprop.h" +#include "crypt.h" +// #include +#include +#include "fpnwapi.h" + +#ifdef DEBUG +int ErrorBoxRetry(LPTSTR szFormat, ...); +#endif + +void ErrorIt(LPTSTR szFormat, ...); +NTSTATUS ACEAdd( PSECURITY_DESCRIPTOR pSD, PSID pSid, ACCESS_MASK AccessMask, ULONG AceFlags, PSECURITY_DESCRIPTOR *ppNewSD ); + +static LPTSTR LocalName = NULL; + +// +3 for leading slashes and ending NULL +static TCHAR CachedServer[MAX_SERVER_NAME_LEN+3]; +static BOOL LocalMachine = FALSE; + +// keep this around so we don't have to keep re-do query +static LPSERVER_INFO_101 ServInfo = NULL; +// #define TYPE_DOMAIN SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_BAKCTRL | SV_TYPE_DOMAIN_MEMBER +#define TYPE_DOMAIN SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_BAKCTRL + +static SAM_HANDLE SAMHandle = (SAM_HANDLE) 0; +static SAM_HANDLE DomainHandle = (SAM_HANDLE) 0; +static PSID DomainID; +static WCHAR UserParms[1024]; + +#define NCP_LSA_SECRET_KEY L"G$MNSEncryptionKey" +#define NCP_LSA_SECRET_LENGTH USER_SESSION_KEY_LENGTH + +static char Secret[USER_SESSION_KEY_LENGTH]; +static HANDLE FPNWLib = NULL; +static DWORD (FAR * NWVolumeAdd) (LPWSTR, DWORD, PNWVOLUMEINFO) = NULL; + +// +// This bit is set when the server is running on a NTAS machine or +// the object is from a trusted domain. NWConv is always on NTAS +// + +#define BINDLIB_REMOTE_DOMAIN_BIAS 0x10000000 + +// +// misc macros that are useful +// +#define SWAPWORD(w) ((WORD)((w & 0xFF) << 8)|(WORD)(w >> 8)) +#define SWAPLONG(l) MAKELONG(SWAPWORD(HIWORD(l)),SWAPWORD(LOWORD(l))) + + +typedef struct _NT_CONN_BUFFER { + struct _NT_CONN_BUFFER *next; + struct _NT_CONN_BUFFER *prev; + + LPTSTR Name; +} NT_CONN_BUFFER; + +static NT_CONN_BUFFER *NTConnListStart = NULL; +static NT_CONN_BUFFER *NTConnListEnd = NULL; + +HANDLE FpnwHandle = NULL; +static FARPROC pFpnwVolumeEnum = NULL; +static FARPROC pFpnwApiBufferFree = NULL; + + +///////////////////////////////////////////////////////////////////////// +LPSTR +FPNWSecretGet( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + Checks the given machine for the FPNW secret. + +Arguments: + + +Return Value: + + +--*/ + +{ + SECURITY_QUALITY_OF_SERVICE QualityOfService; + OBJECT_ATTRIBUTES ObjectAttributes; + LSA_HANDLE PolicyHandle; + LSA_HANDLE SecretHandle; + NTSTATUS Status; + UNICODE_STRING UnicodeSecretName; + PUNICODE_STRING punicodeCurrentValue; + PUSER_INFO_2 pUserInfo = NULL; + + static TCHAR LocServer[MAX_SERVER_NAME_LEN+3]; + UNICODE_STRING UnicodeServerName; + BOOL ret = TRUE; + + memset(Secret, 0, USER_SESSION_KEY_LENGTH); + wsprintf(LocServer, TEXT("\\\\%s"), ServerName); + + // Verify & init secret name. + RtlInitUnicodeString( &UnicodeSecretName, NCP_LSA_SECRET_KEY ); + RtlInitUnicodeString( &UnicodeServerName, LocServer); + + // Prepare to open the policy object. + QualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + QualityOfService.ImpersonationLevel = SecurityImpersonation; + QualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; + QualityOfService.EffectiveOnly = FALSE; + + InitializeObjectAttributes( &ObjectAttributes, NULL, 0L, NULL, NULL ); + ObjectAttributes.SecurityQualityOfService = &QualityOfService; + + // Open a handle to the target machine's LSA policy. + Status = LsaOpenPolicy( &UnicodeServerName, &ObjectAttributes, 0, &PolicyHandle ); + + if( !NT_SUCCESS( Status ) ) { + ret = FALSE; + goto FatalExit0; + } + + // Open the secret object. + Status = LsaOpenSecret( PolicyHandle, &UnicodeSecretName, SECRET_QUERY_VALUE, &SecretHandle ); + + if( !NT_SUCCESS( Status ) ) { + ret = FALSE; + goto FatalExit1; + } + + // Query the secret. + Status = LsaQuerySecret( SecretHandle, &punicodeCurrentValue, NULL, NULL, NULL ); + + if( !NT_SUCCESS( Status ) ) { + ret = FALSE; + goto FatalExit2; + } + + if (punicodeCurrentValue != NULL) { + memcpy(Secret, punicodeCurrentValue->Buffer, USER_SESSION_KEY_LENGTH); + LsaFreeMemory( (PVOID)punicodeCurrentValue ); + } + +FatalExit2: + LsaClose( SecretHandle ); + +FatalExit1: + LsaClose( PolicyHandle ); + +FatalExit0: + + if (ret) + return Secret; + else + return NULL; + +} // FPNWSecretGet + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetGraceLoginAllowed( + USHORT ushGraceLoginAllowed + ) + +/*++ + +Routine Description: + + Store Grace Login Allowed in UserParms. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + USHORT ushTemp = ushGraceLoginAllowed; + UNICODE_STRING uniGraceLoginAllowed; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + + uniGraceLoginAllowed.Buffer = &ushTemp; + uniGraceLoginAllowed.Length = 2; + uniGraceLoginAllowed.MaximumLength = 2; + + err = SetUserProperty (UserParms, GRACELOGINALLOWED, uniGraceLoginAllowed, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + return err; +} // SetGraceLoginAllowed + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetGraceLoginRemainingTimes( + USHORT ushGraceLoginRemainingTimes + ) + +/*++ + +Routine Description: + + Store Grace Login Remaining Times in UserParms. if ushGraceLogin is 0, + "GraceLogin" field will be deleted from UserParms. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + USHORT ushTemp = ushGraceLoginRemainingTimes; + UNICODE_STRING uniGraceLoginRemainingTimes; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + + uniGraceLoginRemainingTimes.Buffer = &ushTemp; + uniGraceLoginRemainingTimes.Length = 2; + uniGraceLoginRemainingTimes.MaximumLength = 2; + + err = SetUserProperty (UserParms, GRACELOGINREMAINING, uniGraceLoginRemainingTimes, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + return err; +} // SetGraceLoginRemainingTimes + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetMaxConnections( + USHORT ushMaxConnections + ) + +/*++ + +Routine Description: + + Store Maximum Concurret Connections in UserParms. If ushMaxConnections + is 0xffff or 0, "MaxConnections" field will be deleted from UserParms, + otherwise the value is stored. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + USHORT ushTemp = ushMaxConnections; + UNICODE_STRING uniMaxConnections; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + + uniMaxConnections.Buffer = &ushMaxConnections; + uniMaxConnections.Length = 2; + uniMaxConnections.MaximumLength = 2; + + err = SetUserProperty (UserParms, MAXCONNECTIONS, uniMaxConnections, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + return err; +} // SetMaxConnections + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetNWPasswordAge( + BOOL fExpired + ) + +/*++ + +Routine Description: + + If fExpired is TRUE, set the NWPasswordSet field to be all fs. + otherwise set it to be the current time. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + LARGE_INTEGER currentTime; + LPWSTR lpNewUserParms = NULL; + UNICODE_STRING uniPasswordAge; + BOOL fUpdate; + + if (fExpired) { + currentTime.HighPart = 0xffffffff; + currentTime.LowPart = 0xffffffff; + } else + NtQuerySystemTime (¤tTime); + + uniPasswordAge.Buffer = (PWCHAR) ¤tTime; + uniPasswordAge.Length = sizeof (LARGE_INTEGER); + uniPasswordAge.MaximumLength = sizeof (LARGE_INTEGER); + + err = SetUserProperty (UserParms, NWTIMEPASSWORDSET, uniPasswordAge, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + if ((err == NERR_Success) &&(lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + return err; +} // SetNWPasswordAge + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetNWPassword( + DWORD dwUserId, + const TCHAR *pchNWPassword, + BOOL ForcePasswordChange + ) + +/*++ + +Routine Description: + + Set "NWPassword" field is fIsNetWareUser is TRUE, Otherwise, delete + the field from UserParms. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err; + TCHAR pchEncryptedNWPassword[NWENCRYPTEDPASSWORDLENGTH + 1]; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + UNICODE_STRING uniPassword; + +#ifdef DEBUG + dprintf(TEXT("Set NetWare password: [%s]\r\n"), pchNWPassword); +#endif + + do { + // Now munge the UserID to the format required by ReturnNetwareForm... + dwUserId |= BINDLIB_REMOTE_DOMAIN_BIAS; + err = ReturnNetwareForm( Secret, dwUserId, pchNWPassword, (UCHAR *) pchEncryptedNWPassword ); + + if ( err != NERR_Success ) + break; + + uniPassword.Buffer = pchEncryptedNWPassword; + uniPassword.Length = NWENCRYPTEDPASSWORDLENGTH * sizeof (WCHAR); + uniPassword.MaximumLength = NWENCRYPTEDPASSWORDLENGTH * sizeof (WCHAR); + + err = SetUserProperty (UserParms, NWPASSWORD, uniPassword, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + + if ((err = SetNWPasswordAge (ForcePasswordChange)) != NERR_Success ) + break; + } + } while (FALSE); + + return err; +} // SetNWPassword + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +SetNWWorkstations( + const TCHAR * pchNWWorkstations + ) + +/*++ + +Routine Description: + + Store NetWare allowed workstation addresses to UserParms. If + pchNWWorkstations is NULL, this function will delete "NWLgonFrom" + field from UserParms. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + UNICODE_STRING uniNWWorkstations; + CHAR * pchTemp = NULL; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + + if (pchNWWorkstations == NULL) { + uniNWWorkstations.Buffer = NULL; + uniNWWorkstations.Length = 0; + uniNWWorkstations.MaximumLength = 0; + } else { + BOOL fDummy; + INT nStringLength = lstrlen(pchNWWorkstations) + 1; + pchTemp = (CHAR *) LocalAlloc (LPTR, nStringLength); + + if ( pchTemp == NULL ) + err = ERROR_NOT_ENOUGH_MEMORY; + + if ( err == NERR_Success && !WideCharToMultiByte (CP_ACP, 0, pchNWWorkstations, nStringLength, pchTemp, nStringLength, NULL, &fDummy)) + err = GetLastError(); + + if ( err == NERR_Success ) { + uniNWWorkstations.Buffer = (WCHAR *) pchTemp; + uniNWWorkstations.Length = nStringLength; + uniNWWorkstations.MaximumLength = nStringLength; + } + } + + err = err? err: SetUserProperty (UserParms, NWLOGONFROM, uniNWWorkstations, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + if (pchTemp != NULL) + LocalFree (pchTemp); + + return err; +} // SetNWWorkstations + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS SetNWHomeDir( + const TCHAR * pchNWHomeDir + ) + +/*++ + +Routine Description: + + Store NetWare Home Directory to UserParms If pchNWWorkstations is NULL, + this function will delete "NWLgonFrom" field from UserParms. + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS err = NERR_Success; + UNICODE_STRING uniNWHomeDir; + CHAR * pchTemp = NULL; + LPWSTR lpNewUserParms = NULL; + BOOL fUpdate; + + if (pchNWHomeDir == NULL) { + uniNWHomeDir.Buffer = NULL; + uniNWHomeDir.Length = 0; + uniNWHomeDir.MaximumLength = 0; + } else { + BOOL fDummy; + INT nStringLength = lstrlen(pchNWHomeDir) + 1; + pchTemp = (CHAR *) LocalAlloc (LPTR, nStringLength); + + if ( pchTemp == NULL ) + err = ERROR_NOT_ENOUGH_MEMORY; + + if ( err == NERR_Success && !WideCharToMultiByte (CP_ACP, 0, pchNWHomeDir, nStringLength, pchTemp, nStringLength, NULL, &fDummy)) + err = GetLastError(); + + if ( err == NERR_Success ) { + uniNWHomeDir.Buffer = (WCHAR *) pchTemp; + uniNWHomeDir.Length = nStringLength; + uniNWHomeDir.MaximumLength = nStringLength; + } + } + + err = err? err : SetUserProperty (UserParms, NWHOMEDIR, uniNWHomeDir, USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate); + + if ((err == NERR_Success) && (lpNewUserParms != NULL)) { + if (fUpdate) + lstrcpyW(UserParms, lpNewUserParms); + + LocalFree(lpNewUserParms); + } + + if (pchTemp != NULL) + LocalFree (pchTemp); + + return err; +} // SetNWHomeDir + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTObjectIDGet( + LPTSTR ObjectName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS status; + UNICODE_STRING UniNewObjectName; + PULONG pRids = NULL; + PSID_NAME_USE pSidNameUse = NULL; + ULONG ObjectID = 0; + + RtlInitUnicodeString(&UniNewObjectName, ObjectName); + + status = SamLookupNamesInDomain(DomainHandle, + 1, + &UniNewObjectName, + &pRids, + &pSidNameUse); + + if ((status == STATUS_SUCCESS) && (pRids != NULL) && (pSidNameUse != NULL)) { + // Found the stupid name - so copy and free SAM garbage + ObjectID = pRids[0]; + ObjectID |= BINDLIB_REMOTE_DOMAIN_BIAS; + + SamFreeMemory(pRids); + SamFreeMemory(pSidNameUse); + } + + return ObjectID; +} // NTObjectIDGet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTSAMParmsSet( + LPTSTR ObjectName, + FPNW_INFO fpnw, + LPTSTR Password, + BOOL ForcePasswordChange + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS status; + UNICODE_STRING UniNewObjectName; + PULONG pRids = NULL; + PSID_NAME_USE pSidNameUse = NULL; + ULONG ObjectID; + SID_NAME_USE SidNameUse; + SAM_HANDLE Handle = (SAM_HANDLE) 0; + PUSER_PARAMETERS_INFORMATION UserParmInfo = NULL; + USER_PARAMETERS_INFORMATION NewUserParmInfo; + LPWSTR lpNewUserParms = NULL; + + RtlInitUnicodeString(&UniNewObjectName, ObjectName); + + status = SamLookupNamesInDomain(DomainHandle, + 1, + &UniNewObjectName, + &pRids, + &pSidNameUse); + + if ((status == STATUS_SUCCESS) && (pRids != NULL) && (pSidNameUse != NULL)) { + // Found the stupid name - so copy and free SAM garbage + ObjectID = pRids[0]; + SidNameUse = pSidNameUse[0]; + + SamFreeMemory(pRids); + SamFreeMemory(pSidNameUse); + + status = SamOpenUser(DomainHandle, + STANDARD_RIGHTS_READ | + STANDARD_RIGHTS_WRITE | + USER_ALL_ACCESS, + ObjectID, + &Handle); + + + // Now get the user parms + if (status == STATUS_SUCCESS) + status = SamQueryInformationUser(Handle, UserParametersInformation, (PVOID *) &UserParmInfo); + + memset(UserParms, 0, sizeof(UserParms)); + if ((status == STATUS_SUCCESS) && (UserParmInfo != NULL)) { + memcpy(UserParms, UserParmInfo->Parameters.Buffer, UserParmInfo->Parameters.Length * sizeof(WCHAR)); + SamFreeMemory(UserParmInfo); + + if ( + ((status = SetNWPassword (ObjectID, Password, ForcePasswordChange)) == NERR_Success) && + ((status = SetMaxConnections (fpnw.MaxConnections)) == NERR_Success) && + ((status = SetGraceLoginAllowed (fpnw.GraceLoginAllowed)) == NERR_Success) && + ((status = SetGraceLoginRemainingTimes (fpnw.GraceLoginRemaining)) == NERR_Success) && + ((status = SetNWWorkstations (fpnw.LoginFrom)) == NERR_Success) && + ((status = SetNWHomeDir (fpnw.HomeDir)) == NERR_Success) ) + { + RtlInitUnicodeString(&NewUserParmInfo.Parameters, UserParms); + status = SamSetInformationUser(Handle, UserParametersInformation, (PVOID) &NewUserParmInfo); + } + + } + } + + if (Handle != (SAM_HANDLE) 0) + SamCloseHandle(Handle); + + return 0; +} // NTSAMParmsSet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTSAMConnect( + LPTSTR ServerName, + LPTSTR DomainName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS status; + OBJECT_ATTRIBUTES object_attrib; + UNICODE_STRING UniDomainName; + UNICODE_STRING UniServerName; + + // + // Do all the garbage for connecting to SAM + // + RtlInitUnicodeString(&UniServerName, ServerName); + RtlInitUnicodeString(&UniDomainName, DomainName); + InitializeObjectAttributes(&object_attrib, NULL, 0, NULL, NULL); + status = SamConnect(&UniServerName, &SAMHandle, SAM_SERVER_ALL_ACCESS, &object_attrib); + + if (status == STATUS_SUCCESS) + status = SamLookupDomainInSamServer(SAMHandle, &UniDomainName, &DomainID); + + if (status == STATUS_SUCCESS) + status = SamOpenDomain(SAMHandle, DOMAIN_ALL_ACCESS, DomainID, &DomainHandle); + + FPNWSecretGet(ServerName); + return (DWORD) status; +} // NTSAMConnect + + +///////////////////////////////////////////////////////////////////////// +VOID +NTSAMClose() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + if (DomainHandle != (SAM_HANDLE) 0) + SamCloseHandle(DomainHandle); + + if (DomainID != (PSID) 0) + SamFreeMemory(DomainID); + + if (SAMHandle != (SAM_HANDLE) 0) + SamCloseHandle(SAMHandle); + + SAMHandle = (SAM_HANDLE) 0; + DomainHandle = (SAM_HANDLE) 0; + DomainID = (PSID) 0; + +} // NTSAMClose + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTServerSet( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + + // Fixup the destination server name + lstrcpy(CachedServer, TEXT("\\\\")); + lstrcat(CachedServer, ServerName); + + if (!LocalName) + GetLocalName(&LocalName); + + if (lstrcmpi(ServerName, LocalName) == 0) + LocalMachine = TRUE; + else + LocalMachine = FALSE; + + if (FpnwHandle == NULL) + FpnwHandle = LoadLibrary(TEXT("FPNWCLNT.DLL")); + + if ((FpnwHandle != NULL) && (pFpnwVolumeEnum == NULL)) { + pFpnwVolumeEnum = GetProcAddress(FpnwHandle, ("FpnwVolumeEnum")); + pFpnwApiBufferFree = GetProcAddress(FpnwHandle, ("FpnwApiBufferFree")); + } + + return (0); + +} // NTServerSet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTServerFree() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LocalMachine = FALSE; + lstrcpy(CachedServer, TEXT("")); + return (0); + +} // NTServerFree + + +///////////////////////////////////////////////////////////////////////// +DWORD +FPNWShareAdd( + LPTSTR ShareName, + LPTSTR Path + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NET_API_STATUS Status = 0; + NWVOLUMEINFO NWVol; + + if (FPNWLib == NULL) + FPNWLib = LoadLibrary(TEXT("FPNWCLNT.DLL")); + + if (FPNWLib == NULL) + return 1; + + if (NWVolumeAdd == NULL) + NWVolumeAdd = (DWORD (FAR * ) (LPWSTR, DWORD, PNWVOLUMEINFO)) GetProcAddress(FPNWLib, "NwVolumeAdd"); + + NWVol.lpVolumeName = AllocMemory((lstrlen(ShareName) + 1) * sizeof(TCHAR)); + NWVol.lpPath = AllocMemory((lstrlen(Path) + 1) * sizeof(TCHAR)); + if ((NWVol.lpVolumeName == NULL) || (NWVol.lpPath == NULL)) + return 1; + + lstrcpy(NWVol.lpVolumeName, ShareName); + NWVol.dwType = NWVOL_TYPE_DISKTREE; + NWVol.dwMaxUses = NWVOL_MAX_USES_UNLIMITED; + NWVol.dwCurrentUses = 0; + lstrcpy(NWVol.lpPath, Path); + + if (LocalMachine) + Status = NWVolumeAdd(NULL, 1, &NWVol); + else + Status = NWVolumeAdd(CachedServer, 1, &NWVol); + + return Status; + +} // FPNWShareAdd + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTShareAdd( + LPTSTR ShareName, + LPTSTR Path + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NET_API_STATUS Status = 0; + SHARE_INFO_2 shi2; + DWORD parmerr; + + memset(&shi2, 0, sizeof(SHARE_INFO_2)); + + shi2.shi2_netname = ShareName; + shi2.shi2_type = STYPE_DISKTREE; + shi2.shi2_max_uses = (DWORD) 0xffffffff; + shi2.shi2_path = Path; + + if (LocalMachine) + Status = NetShareAdd(NULL, 2, (LPBYTE) &shi2, &parmerr); + else + Status = NetShareAdd(CachedServer, 2, (LPBYTE) &shi2, &parmerr); + + return Status; + +} // NTShareAdd + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTUsersEnum( + USER_LIST **lpUserList + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPUSER_INFO_0 buffer = NULL; + NET_API_STATUS Status = 0; + DWORD prefmaxlength = 0xffffffff; + DWORD totalentries = 0; + DWORD entriesread = 0; + DWORD resumehandle = 0; + DWORD i; + USER_LIST *UserList = NULL; + USER_BUFFER *UserBuffer = NULL; + + if (LocalMachine) + Status = NetUserEnum(NULL, 0, 0, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + else + Status = NetUserEnum(CachedServer, 0, 0, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + + if (Status == NO_ERROR) { + + UserList = AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * entriesread)); + + if (!UserList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = UserList->UserBuffer; + + for (i = 0; i < entriesread; i++) { + lstrcpy(UserBuffer[i].Name, buffer[i].usri0_name); + lstrcpy(UserBuffer[i].NewName, buffer[i].usri0_name); + } + + qsort((void *) UserBuffer, (size_t) entriesread, sizeof(USER_BUFFER), UserListCompare); + } + } + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + if (UserList != NULL) + UserList->Count = entriesread; + + *lpUserList = UserList; + return Status; + +} // NTUsersEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTGroupsEnum( + GROUP_LIST **lpGroupList + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPGROUP_INFO_0 buffer = NULL; + NET_API_STATUS Status = 0; + DWORD prefmaxlength = 0xffffffff; + DWORD totalentries = 0; + DWORD entriesread = 0; + DWORD resumehandle = 0; + DWORD i; + GROUP_LIST *GroupList = NULL; + GROUP_BUFFER *GroupBuffer = NULL; + + if (LocalMachine) + Status = NetGroupEnum(NULL, 0, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + else + Status = NetGroupEnum(CachedServer, 0, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + + if (Status == NO_ERROR) { + + GroupList = AllocMemory(sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER) * entriesread)); + + if (!GroupList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + GroupBuffer = GroupList->GroupBuffer; + + for (i = 0; i < entriesread; i++) { + lstrcpy(GroupBuffer[i].Name, buffer[i].grpi0_name); + lstrcpy(GroupBuffer[i].NewName, buffer[i].grpi0_name); + } + } + } + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + if (GroupList != NULL) + GroupList->Count = entriesread; + + *lpGroupList = GroupList; + return Status; + +} // NTGroupsEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTDomainEnum( + SERVER_BROWSE_LIST **lpServList + ) + +/*++ + +Routine Description: + + Enumerates all NT servers in a given domain. + +Arguments: + + +Return Value: + + +--*/ + +{ + LPSERVER_INFO_101 buffer = NULL; + NET_API_STATUS Status = 0; + DWORD prefmaxlength = 0xffffffff; + DWORD totalentries = 0; + DWORD entriesread = 0; + DWORD resumehandle = 0; + DWORD i; + BOOL Container = FALSE; + SERVER_BROWSE_LIST *ServList = NULL; + SERVER_BROWSE_BUFFER *SList; + + Status = NetServerEnum(NULL, 101, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, SV_TYPE_DOMAIN_ENUM, NULL, &resumehandle); + + if (Status == NO_ERROR) { + + ServList = AllocMemory(sizeof(SERVER_BROWSE_LIST) + (sizeof(SERVER_BROWSE_BUFFER) * entriesread)); + + if (!ServList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + ServList->Count = entriesread; + SList = (SERVER_BROWSE_BUFFER *) &ServList->SList; + + for (i = 0; i < entriesread; i++) { + lstrcpy(SList[i].Name, buffer[i].sv101_name); + lstrcpy(SList[i].Description, buffer[i].sv101_comment); + SList[i].Container = FALSE; + SList[i].child = NULL; + } + } + } + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + *lpServList = ServList; + return Status; + +} // NTDomainEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTServerEnum( + LPTSTR szContainer, + SERVER_BROWSE_LIST **lpServList + ) + +/*++ + +Routine Description: + + Enumerates all NT servers in a given domain. + +Arguments: + + +Return Value: + + +--*/ + +{ + LPSERVER_INFO_101 buffer = NULL; + NET_API_STATUS Status = 0; + DWORD prefmaxlength = 0xffffffff; + DWORD totalentries = 0; + DWORD entriesread = 0; + DWORD resumehandle = 0; + DWORD i; + BOOL Container = FALSE; + SERVER_BROWSE_LIST *ServList = NULL; + SERVER_BROWSE_BUFFER *SList; + + if (((szContainer != NULL) && (lstrlen(szContainer)))) + Container = TRUE; + + if (Container) + Status = NetServerEnum(NULL, 101, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, SV_TYPE_NT, szContainer, &resumehandle); + else + Status = NetServerEnum(NULL, 101, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, SV_TYPE_DOMAIN_ENUM, NULL, &resumehandle); + + if (Status == NO_ERROR) { + + ServList = AllocMemory(sizeof(SERVER_BROWSE_LIST) + (sizeof(SERVER_BROWSE_BUFFER) * entriesread)); + + if (!ServList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + ServList->Count = entriesread; + SList = (SERVER_BROWSE_BUFFER *) &ServList->SList; + + for (i = 0; i < entriesread; i++) { + lstrcpy(SList[i].Name, buffer[i].sv101_name); + lstrcpy(SList[i].Description, buffer[i].sv101_comment); + SList[i].Container = !Container; + SList[i].child = NULL; + } + } + } + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + *lpServList = ServList; + return Status; + +} // NTServerEnum + + +///////////////////////////////////////////////////////////////////////// +BOOL +NTShareNameValidate( + LPTSTR szShareName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR *ptr = szShareName; + BOOL ret; + + ret = TRUE; + + if (*ptr) { + // go to end + while (*ptr) + ptr++; + + // now back up to last character + ptr--; + if (*ptr == TEXT('$')) // for ADMIN$, IPC$, etc... + ret = FALSE; + + } else + // Don't allow zero length - not sure why we would ever get these... + ret = FALSE; + + return ret; + +} // NTShareNameValidate + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTSharesEnum( + SHARE_LIST **lpShares, + DRIVE_LIST *Drives + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPSHARE_INFO_2 buffer = NULL; + NET_API_STATUS Status = 0; + DWORD prefmaxlength = 0xffffffff; + DWORD totalentries = 0; + DWORD entriesread = 0; + DWORD ActualEntries = 0; + DWORD resumehandle = 0; + DWORD i, di; + SHARE_LIST *ShareList = NULL; + SHARE_BUFFER *SList; + DRIVE_BUFFER *DList; + ULONG TotalDrives; + TCHAR Drive[2]; + PFPNWVOLUMEINFO VolumeInfo, VolumeEntry; + BOOL Found; + + if (LocalMachine) + Status = NetShareEnum(NULL, 2, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + else + Status = NetShareEnum(CachedServer, 2, (LPBYTE *) &buffer, prefmaxlength, &entriesread, &totalentries, &resumehandle); + + if (Status == NO_ERROR) { + + // We have the list - but need to prune out IPC$, Admin$, etc... + for (i = 0; i < entriesread; i++) + if ((buffer[i].shi2_type == STYPE_DISKTREE) && NTShareNameValidate(buffer[i].shi2_netname)) + ActualEntries++; + + ShareList = AllocMemory(sizeof(SHARE_LIST) + (sizeof(SHARE_BUFFER) * ActualEntries)); + + if (!ShareList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + SList = (SHARE_BUFFER *) &ShareList->SList; + + ShareList->Count = ActualEntries; + ActualEntries = 0; + + TotalDrives = 0; + Drive[1] = TEXT('\0'); + if (Drives != NULL) { + DList = Drives->DList; + TotalDrives = Drives->Count; + } + + // loop through copying the data + for (i = 0; i < entriesread; i++) + if ((buffer[i].shi2_type == STYPE_DISKTREE) && NTShareNameValidate(buffer[i].shi2_netname)) { + lstrcpy(SList[ActualEntries].Name, buffer[i].shi2_netname); + lstrcpy(SList[ActualEntries].Path, buffer[i].shi2_path); + SList[ActualEntries].Index = (USHORT) ActualEntries; + + // Scan drive list looking for match to share path + for (di = 0; di < TotalDrives; di++) { + // Get first char from path - should be drive letter + Drive[0] = *buffer[i].shi2_path; + if (!lstrcmpi(Drive, DList[di].Drive)) + SList[ActualEntries].Drive = &DList[di]; + } + + ActualEntries++; + } + + } + } + + // + // Now loop through any FPNW shares and tack those on as well + // + VolumeInfo = NULL; + resumehandle = entriesread = 0; + + if (pFpnwVolumeEnum != NULL) + if (LocalMachine) + Status = (*pFpnwVolumeEnum) ( NULL, 1, (LPBYTE *)&VolumeInfo, &entriesread, &resumehandle ); + else + Status = (*pFpnwVolumeEnum) ( CachedServer, 1, (LPBYTE *)&VolumeInfo, &entriesread, &resumehandle ); + +#if DBG +dprintf(TEXT("Status: 0x%lX Entries: %lu\n"), Status, entriesread); +#endif + if ( !Status && entriesread ) { + + if (ShareList) + ShareList = ReallocMemory(ShareList, sizeof(SHARE_LIST) + (sizeof(SHARE_BUFFER) * (ActualEntries + entriesread))); + else + ShareList = AllocMemory(sizeof(SHARE_LIST) + (sizeof(SHARE_BUFFER) * entriesread)); + + if (!ShareList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + SList = (SHARE_BUFFER *) &ShareList->SList; // reset pointer... + + // loop through copying the data + for (i = 0; i < entriesread; i++) { + // + // Make sure not in NT Share list already + // + Found = FALSE; + + for (di = 0; di < ShareList->Count; di++) + if (!lstrcmpi(SList[di].Name, VolumeInfo[i].lpVolumeName)) + Found = TRUE; + + if ((!Found) && (VolumeInfo[i].dwType == FPNWVOL_TYPE_DISKTREE) ) { + lstrcpy(SList[ActualEntries].Name, VolumeInfo[i].lpVolumeName); + lstrcpy(SList[ActualEntries].Path, VolumeInfo[i].lpPath); + SList[ActualEntries].Index = (USHORT) ActualEntries; + + // Scan drive list looking for match to share path + for (di = 0; di < TotalDrives; di++) { + // Get first char from path - should be drive letter + Drive[0] = *VolumeInfo[i].lpPath; + if (!lstrcmpi(Drive, DList[di].Drive)) + SList[ActualEntries].Drive = &DList[di]; + } + + ActualEntries++; + } + } + } + } + + if (ShareList) + ShareList->Count = ActualEntries; + + if (VolumeInfo && (pFpnwApiBufferFree != NULL)) + (*pFpnwApiBufferFree) ( VolumeInfo ); + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + *lpShares = ShareList; + return Status; +} // NTSharesEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTGroupSave( + LPTSTR Name + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static NET_API_STATUS Status = 0; + GROUP_INFO_0 grpi0; + DWORD err; + + grpi0.grpi0_name = Name; + + if (LocalMachine) + Status = NetGroupAdd(NULL, 0, (LPBYTE) &grpi0, &err); + else { + Status = NetGroupAdd(CachedServer, 0, (LPBYTE) &grpi0, &err); + } + return Status; + +} // NTGroupSave + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTGroupUserAdd( + LPTSTR GroupName, + LPTSTR UserName, + BOOL Local + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NET_API_STATUS Status = 0; + SID *pUserSID = NULL; + + if (LocalMachine) + if (Local) { + pUserSID = NTSIDGet(NULL, UserName); + + if (pUserSID != NULL) + Status = NetLocalGroupAddMember(NULL, GroupName, pUserSID); + + } else + Status = NetGroupAddUser(NULL, GroupName, UserName); + else { + if (Local) { + pUserSID = NTSIDGet(CachedServer, UserName); + + if (pUserSID != NULL) + Status = NetLocalGroupAddMember(CachedServer, GroupName, pUserSID); + } else + Status = NetGroupAddUser(CachedServer, GroupName, UserName); + } + + // If complaining because user is already there, ignore + if (Status == NERR_UserInGroup) + Status = 0; + + return Status; + +} // NTGroupUserAdd + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTUserInfoSave( + NT_USER_INFO *NT_UInfo, + PFPNW_INFO fpnw + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static NET_API_STATUS Status = 0; + struct _USER_INFO_3 *usri3; + DWORD err; + + usri3 = (struct _USER_INFO_3 *) NT_UInfo; + + // Map logon hours to GMT time - as NetAPI re-fixes it + NetpRotateLogonHours(NT_UInfo->logon_hours, UNITS_PER_WEEK, TRUE); + + if (LocalMachine) + Status = NetUserAdd(NULL, 3, (LPBYTE) usri3, &err); + else + Status = NetUserAdd(CachedServer, 3, (LPBYTE) usri3, &err); + + if ((!Status) && (fpnw != NULL)) { + // Need to get user info via LSA call before calling setuserparms + } + + return Status; + +} // NTUserInfoSave + + +#define NEW_NULL_PASSWD TEXT(" ") +///////////////////////////////////////////////////////////////////////// +DWORD +NTUserInfoSet( + NT_USER_INFO *NT_UInfo, + PFPNW_INFO fpnw + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPWSTR Password; + LPWSTR Name; + static NET_API_STATUS Status = 0; + struct _USER_INFO_3 *usri3; + DWORD err; + + // Tell it not to replace the password + Password = NT_UInfo->password; + NT_UInfo->password = NULL; + + Name = NT_UInfo->name; + usri3 = (struct _USER_INFO_3 *) NT_UInfo; + + // Map logon hours to GMT time - as NetAPI re-fixes it + NetpRotateLogonHours(NT_UInfo->logon_hours, UNITS_PER_WEEK, TRUE); + + if (LocalMachine) + Status = NetUserSetInfo(NULL, Name, 3, (LPBYTE) usri3, &err); + else + Status = NetUserSetInfo(CachedServer, Name, 3, (LPBYTE) usri3, &err); + + if ((!Status) && (fpnw != NULL)) { + } + + // Reset the password in our data structure. + NT_UInfo->password = Password; + return Status; + +} // NTUserInfoSet + + +///////////////////////////////////////////////////////////////////////// +VOID +NTUserRecInit( + LPTSTR UserName, + NT_USER_INFO *NT_UInfo + ) + +/*++ + +Routine Description: + + Initializes a user record, uses static variables for string holders + so is not re-entrant, and will overwrite previous records data if + called again. + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR uname[UNLEN + 1]; + static TCHAR upassword[ENCRYPTED_PWLEN]; + static TCHAR uhomedir[PATHLEN + 1]; + static TCHAR ucomment[MAXCOMMENTSZ + 1]; + static TCHAR uscriptpath[PATHLEN + 1]; + static TCHAR ufullname[MAXCOMMENTSZ + 1]; + static TCHAR uucomment[MAXCOMMENTSZ + 1]; + static TCHAR uparms[MAXCOMMENTSZ + 1]; + static TCHAR uworkstations[1]; + static BYTE ulogonhours[21]; + static TCHAR ulogonserver[1]; + static TCHAR uprofile[1]; + static TCHAR uhome_dir_drive[1]; + + // init all the static data holders. + memset(uname, 0, sizeof( uname )); + lstrcpy(uname, UserName); + + memset(upassword, 0, sizeof( upassword )); + memset(uhomedir, 0, sizeof( uhomedir )); + memset(ucomment, 0, sizeof( ucomment )); + memset(uscriptpath, 0, sizeof( uscriptpath )); + memset(ufullname, 0, sizeof( ufullname )); + memset(uucomment, 0, sizeof( uucomment )); + memset(uparms, 0, sizeof( uparms )); + memset(uworkstations, 0, sizeof( uworkstations )); + memset(ulogonhours, 0, sizeof( ulogonhours )); + memset(ulogonserver, 0, sizeof( ulogonserver )); + memset(uprofile, 0, sizeof( uprofile )); + memset(uhome_dir_drive, 0, sizeof( uhome_dir_drive )); + + memset(NT_UInfo, 0, sizeof(NT_USER_INFO)); + + // point the passed in record to these data holders + NT_UInfo->name = uname; + NT_UInfo->password = upassword; + NT_UInfo->home_dir = uhomedir; + NT_UInfo->comment = ucomment; + NT_UInfo->script_path = uscriptpath; + NT_UInfo->full_name = ufullname; + NT_UInfo->usr_comment = uucomment; + NT_UInfo->parms = uparms; + NT_UInfo->workstations = uworkstations; + NT_UInfo->logon_hours = ulogonhours; + NT_UInfo->logon_server = ulogonserver; + NT_UInfo->profile = uprofile; + NT_UInfo->home_dir_drive = uhome_dir_drive; + NT_UInfo->units_per_week = UNITS_PER_WEEK; + + // Set the default values for special fields + NT_UInfo->primary_group_id = DOMAIN_GROUP_RID_USERS; + NT_UInfo->priv = USER_PRIV_USER; + NT_UInfo->acct_expires = TIMEQ_FOREVER; + NT_UInfo->max_storage = USER_MAXSTORAGE_UNLIMITED; + NT_UInfo->flags = UF_SCRIPT; + +} // NTUserRecInit + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +NTDriveShare( + LPTSTR DriveLetter + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR RootPath[MAX_SERVER_NAME_LEN + 3]; + + if (LocalMachine) + wsprintf(RootPath, TEXT("%s:\\"), DriveLetter); + else + wsprintf(RootPath, TEXT("%s\\%s$\\"), CachedServer, DriveLetter); + + return RootPath; + +} // NTDriveShare + + +///////////////////////////////////////////////////////////////////////// +VOID +NTDriveInfoGet( + DRIVE_BUFFER *DBuff + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD volMaxCompLength, volFileSystemFlags; + DWORD sectorsPC, bytesPS, FreeClusters, Clusters; + TCHAR NameBuffer[20]; + TCHAR volName[20]; + LPTSTR RootPath; + UINT previousErrorMode; + + // + // Disable DriveAccess Error, because no media is inserted onto specified drive. + // + previousErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS| + SEM_NOOPENFILEERRORBOX); + + volMaxCompLength = volFileSystemFlags = 0; + sectorsPC = bytesPS = FreeClusters = Clusters = 0; + + // First get file system type + RootPath = NTDriveShare(DBuff->Drive); + if (GetVolumeInformation(RootPath, volName, sizeof(volName), NULL, &volMaxCompLength, &volFileSystemFlags, NameBuffer, sizeof(NameBuffer))) { + if (GetDriveType(RootPath) == DRIVE_CDROM) + lstrcpy(DBuff->DriveType, Lids(IDS_S_49)); + else + lstrcpyn(DBuff->DriveType, NameBuffer, sizeof(DBuff->DriveType)-1); + + lstrcpyn(DBuff->Name, volName, sizeof(DBuff->Name)-1); + + if (!lstrcmpi(NameBuffer, Lids(IDS_S_9))) + DBuff->Type = DRIVE_TYPE_NTFS; + } + else { + if (GetDriveType(RootPath) == DRIVE_CDROM) + lstrcpy(DBuff->DriveType, Lids(IDS_S_49)); + else + lstrcpy(DBuff->DriveType, TEXT("\0")); + + lstrcpy(DBuff->Name, TEXT("\0")); + + if (!lstrcmpi(NameBuffer, Lids(IDS_S_9))) + DBuff->Type = DRIVE_TYPE_NTFS; + } + + if (GetDiskFreeSpace(RootPath, §orsPC, &bytesPS, &FreeClusters, &Clusters)) { + DBuff->TotalSpace = Clusters * sectorsPC * bytesPS; + DBuff->FreeSpace = FreeClusters * sectorsPC * bytesPS; + } + else { + DBuff->TotalSpace = 0; + DBuff->FreeSpace = 0; + } + + // + // Back to original error mode. + // + SetErrorMode(previousErrorMode); + +} // NTDriveInfoGet + + +///////////////////////////////////////////////////////////////////////// +BOOL +NTDriveValidate( + TCHAR DriveLetter + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL ret = FALSE; + + // Just make sure it isn't one of the two floppys + if (!((DriveLetter == TEXT('A')) || (DriveLetter == TEXT('B')))) + ret = TRUE; + + return ret; + +} // NTDriveValidate + + +///////////////////////////////////////////////////////////////////////// +VOID +NTDrivesEnum( + DRIVE_LIST **lpDrives + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR *buffer = NULL; + NET_API_STATUS Status = 0; + DWORD entriesread, totalentries, resumehandle, actualentries, i; + DRIVE_LIST *DriveList; + DRIVE_BUFFER *DList; + + entriesread = totalentries = resumehandle = actualentries = 0; + + if (LocalMachine) + Status = NetServerDiskEnum(NULL, 0, (LPBYTE *) &buffer, 0xFFFFFFFF, &entriesread, &totalentries, &resumehandle); + else + Status = NetServerDiskEnum(CachedServer, 0, (LPBYTE *) &buffer, 0xFFFFFFFF, &entriesread, &totalentries, &resumehandle); + + if (Status == NO_ERROR) { + // We have the list - but need to prune out A:, B: + for (i = 0; i < entriesread; i++) + if (NTDriveValidate(buffer[i * 3])) + actualentries++; + + // temporarily use i to hold total size of data structure + i = sizeof(DRIVE_LIST) + (sizeof(DRIVE_BUFFER) * actualentries); + DriveList = AllocMemory(i); + + if (!DriveList) { + Status = ERROR_NOT_ENOUGH_MEMORY; + } else { + memset(DriveList, 0, i); + DList = (DRIVE_BUFFER *) &DriveList->DList; + DriveList->Count = actualentries; + + // Now fill in the individual data items + actualentries = 0; + for (i = 0; i < entriesread; i++) + if (NTDriveValidate(buffer[i * 3])) { + DList[actualentries].Drive[0] = buffer[i * 3]; + NTDriveInfoGet(&DList[actualentries]); + actualentries++; + } + } + } + + if (buffer != NULL) + NetApiBufferFree((LPVOID) buffer); + + *lpDrives = DriveList; + return; + +} // NTDrivesEnum + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServerGetInfo( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + NET_API_STATUS Status = 0; + + if (ServInfo != NULL) + NetApiBufferFree((LPVOID) ServInfo); + + ServInfo = NULL; + + wsprintf(LocServer, TEXT("\\\\%s"), ServerName); + + if (!LocalName) + GetLocalName(&LocalName); + + if (lstrcmpi(ServerName, LocalName) == 0) + Status = NetServerGetInfo(NULL, 101, (LPBYTE *) &ServInfo); + else + Status = NetServerGetInfo(LocServer, 101, (LPBYTE *) &ServInfo); + + if (Status) { + ServInfo = NULL; + return; + } + +} // NTServerGetInfo + + +///////////////////////////////////////////////////////////////////////// +NT_CONN_BUFFER * +NTConnListFind( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL Found = FALSE; + static NT_CONN_BUFFER *ServList; + + ServList = NTConnListStart; + + while ((ServList && !Found)) { + if (!lstrcmpi(ServList->Name, ServerName)) + Found = TRUE; + else + ServList = ServList->next; + } + + if (!Found) + ServList = NULL; + + return (ServList); + +} // NTConnListFind + + +///////////////////////////////////////////////////////////////////////// +NT_CONN_BUFFER * +NTConnListAdd( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static NT_CONN_BUFFER *tmpPtr; + ULONG Size, strlen1; + + tmpPtr = NULL; + strlen1 = (lstrlen(ServerName) + 1) * sizeof(TCHAR); + Size = sizeof(NT_CONN_BUFFER) + strlen1; + tmpPtr = AllocMemory(Size); + + if (tmpPtr != NULL) { + // init it to NULL's + memset(tmpPtr, 0, Size); + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(NT_CONN_BUFFER)); + lstrcpy(tmpPtr->Name, ServerName); + + // link it into the list + if (!NTConnListStart) + NTConnListStart = NTConnListEnd = tmpPtr; + else { + NTConnListEnd->next = tmpPtr; + tmpPtr->prev = NTConnListEnd; + NTConnListEnd = tmpPtr; + } + } + + return (tmpPtr); + +} // NTConnListAdd + + +///////////////////////////////////////////////////////////////////////// +VOID +NTConnListDelete( + NT_CONN_BUFFER *tmpPtr + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NT_CONN_BUFFER *PrevPtr; + NT_CONN_BUFFER *NextPtr; + + if (tmpPtr == NULL) + return; + + // Now unlink the actual server record + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (NTConnListEnd == tmpPtr) + NTConnListEnd = PrevPtr; + + // Check if at start of list + if (NTConnListStart == tmpPtr) + NTConnListStart = NextPtr; + + FreeMemory(tmpPtr); + +} // NTConnListDelete + + +///////////////////////////////////////////////////////////////////////// +VOID +NTConnListDeleteAll() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + NT_CONN_BUFFER *ServList; + NT_CONN_BUFFER *ServListNext; + + // Now remove the entries from the internal list + ServList = NTConnListStart; + + while (ServList) { + ServListNext = ServList->next; + + wsprintf(LocServer, Lids(IDS_S_10), ServList->Name); + WNetCancelConnection2(LocServer, 0, FALSE); + + NTConnListDelete(ServList); + ServList = ServListNext; + } + +} // NTConnListDeleteAll + + +///////////////////////////////////////////////////////////////////////// +VOID +NTUseDel( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + NT_CONN_BUFFER *NTConn; + + // Find it in our connection list - if it exists get rid of it. + NTConn = NTConnListFind(ServerName); + if (NTConn != NULL) + NTConnListDelete(NTConn); + + NTServerFree(); + wsprintf(LocServer, Lids(IDS_S_10), ServerName); + WNetCancelConnection2(LocServer, 0, FALSE); + +} // NTUseDel + + +///////////////////////////////////////////////////////////////////////// +BOOL +NTServerValidate( + HWND hWnd, + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + Validates a given server - makes sure it can be connected to and + that the user has admin privs on it. + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL ret = FALSE; + DWORD idsErr = 0; + DWORD lastErr = 0; + DWORD Size; + NET_API_STATUS Status; + LPUSER_INFO_1 UserInfo1 = NULL; + TCHAR UserName[MAX_NT_USER_NAME_LEN + 1]; + TCHAR ServName[MAX_SERVER_NAME_LEN + 3]; // +3 for leading slashes and ending NULL + LPVOID lpMessageBuffer = NULL; + + NTServerSet(ServerName); + + // server already connected then return success + if (NTConnListFind(ServerName)) { + return TRUE; + } + + CursorHourGlass(); + + // Get Current Logged On User + lstrcpy(UserName, TEXT("")); + Size = sizeof(UserName); + WNetGetUser(NULL, UserName, &Size); + + // Fixup the destination server name + lstrcpy(ServName, TEXT( "\\\\" )); + lstrcat(ServName, ServerName); + + // Make an ADMIN$ connection to the server + if (UseAddPswd(hWnd, UserName, ServName, Lids(IDS_S_11), NT_PROVIDER)) { + + // Double check we have admin privs + // Get connection to the system and check for admin privs... + Status = NetUserGetInfo(ServName, UserName, 1, (LPBYTE *) &UserInfo1); + + if (Status == ERROR_SUCCESS) { + + // Got User info, now make sure admin flag is set + if (!(UserInfo1->usri1_priv & USER_PRIV_ADMIN)) { + idsErr = IDS_E_6; + goto cleanup; + } + + // We may have a connection to admin$ and we may have proven + // that the user we made the connection with really is an admin + // but sitting at the local machine we still may have a problem + // acquiring all of the administrative information necessary to + // accomplish a successful conversion. each and every one of the + // functions that make network calls should return errors and if + // that were the case then the errors would propagate up and we + // could deal with the access denial reasonably. unfortunately, + // alot of assumptions are made after the success of this call + // so we must perform yet another test here... + if (LocalMachine) { + + DWORD EntriesRead = 0; + DWORD TotalEntries = 0; + LPSHARE_INFO_2 ShareInfo2 = NULL; + + Status = NetShareEnum( + ServName, + 2, + (LPBYTE *) &ShareInfo2, + MAX_PREFERRED_LENGTH, + &EntriesRead, + &TotalEntries, + NULL + ); + + if (ShareInfo2 != NULL) + NetApiBufferFree((LPVOID) ShareInfo2); // discarded... + + if (Status != ERROR_SUCCESS) { + idsErr = (Status == ERROR_ACCESS_DENIED) ? IDS_E_6 : IDS_E_5; + goto cleanup; + } + } + + // Now get server info and make certain this is an NT server + // instead of an LM type server. Note: Info from the call is + // cached and used later, so don't remove it!! + NTServerGetInfo(ServerName); + + if (ServInfo) { + + if (ServInfo->sv101_platform_id == SV_PLATFORM_ID_NT) { + + if (ServInfo->sv101_type & (TYPE_DOMAIN)) { + + // If NTAS and have admin privs then we are set + // then add it to our connection list... + NTConnListAdd(ServerName); + ret = TRUE; + + } else { + idsErr = IDS_E_8; + } + + } else { + idsErr = IDS_E_8; + } + + } else { + idsErr = IDS_E_7; + } + + } else { + + // determine error string id and bail out... + idsErr = (Status == ERROR_ACCESS_DENIED) ? IDS_E_6 : IDS_E_5; + } + + } else if (lastErr = GetLastError()) { + + // error string id + idsErr = IDS_E_9; + + // use system default language resource + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + lastErr, + 0, + (LPTSTR)&lpMessageBuffer, + 0, + NULL + ); + + } + +cleanup: + + if (lpMessageBuffer) { + WarningError(Lids((WORD)(DWORD)idsErr), ServerName, lpMessageBuffer); + LocalFree(lpMessageBuffer); + } else if (idsErr) { + WarningError(Lids((WORD)(DWORD)idsErr), ServerName); + } + + if (UserInfo1 != NULL) + NetApiBufferFree((LPVOID) UserInfo1); + + CursorNormal(); + return ret; + +} // NTServerValidate + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServerInfoReset( + HWND hWnd, + DEST_SERVER_BUFFER *DServ, + BOOL ResetDomain + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR apiPDCName = NULL; + TCHAR PDCName[MAX_SERVER_NAME_LEN + 1]; + TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + DOMAIN_BUFFER *DBuff; + TCHAR Domain[DNLEN + 1]; + NET_API_STATUS Status = 0; + + lstrcpy(PDCName, TEXT("")); + + if (ServInfo) { + DServ->Type = ServInfo->sv101_type; + DServ->VerMaj = ServInfo->sv101_version_major; + DServ->VerMin = ServInfo->sv101_version_minor; + DServ->IsNTAS = IsNTAS(DServ->Name); + DServ->IsFPNW = IsFPNW(DServ->Name); + + // If there was no old domain, don't worry about reseting it + if (ResetDomain && (DServ->Domain == NULL)) + ResetDomain = FALSE; + + // Check if we are a member of a domain. + if (ServInfo->sv101_type & (TYPE_DOMAIN)) { + wsprintf(LocServer, TEXT("\\\\%s"), DServ->Name); + Status = NetGetDCName(LocServer, NULL, (LPBYTE *) &apiPDCName); + + if (!Status) { + // get rid of leading 2 backslashes + if (lstrlen(apiPDCName) > 2) + lstrcpy(PDCName, &apiPDCName[2]); + + if (NTServerValidate(hWnd, PDCName)) { + DServ->IsFPNW = IsFPNW(PDCName); + DServ->InDomain = TRUE; + + // Get Domain + memset(Domain, 0, sizeof(Domain)); + NTDomainGet(DServ->Name, Domain); + + if (ResetDomain) { + DomainListDelete(DServ->Domain); + DServ->Domain = NULL; + } + + // Check if we need to add server to server list + DBuff = DomainListFind(Domain); + + if (DBuff == NULL) { + DBuff = DomainListAdd(Domain, PDCName); + DBuff->Type = ServInfo->sv101_type; + DBuff->VerMaj = ServInfo->sv101_version_major; + DBuff->VerMin = ServInfo->sv101_version_minor; + } + + DBuff->UseCount++; + DServ->Domain = DBuff; + } // if Domain valid + + if (apiPDCName != NULL) + NetApiBufferFree((LPVOID) apiPDCName); + } + + } + + } + + // make sure we are pointing to the right one + NTServerSet(DServ->Name); + + // Fill in Drive Lists + NTDrivesEnum(&DServ->DriveList); + +} // NTServerInfoReset + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServerInfoSet( + HWND hWnd, + LPTSTR ServerName, + DEST_SERVER_BUFFER *DServ + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR apiPDCName = NULL; + NET_API_STATUS Status = 0; + + CursorHourGlass(); + DServ->UseCount++; + + NTServerInfoReset(hWnd, DServ, FALSE); + + // Fill in share and Drive Lists + NTSharesEnum(&DServ->ShareList, DServ->DriveList); + + +#ifdef DEBUG +{ + DWORD i; + + dprintf(TEXT("Adding NT Server: %s\n"), DServ->Name); + dprintf(TEXT(" Version: %lu.%lu\n"), DServ->VerMaj, DServ->VerMin); + + if (DServ->InDomain && DServ->Domain) + dprintf(TEXT(" In Domain: %s [\\\\%s]\n"), DServ->Domain->Name, DServ->Domain->PDCName); + + dprintf(TEXT("\n")); + dprintf(TEXT(" Drives:\n")); + dprintf(TEXT(" +-------------------+\n")); + for (i = 0; i < DServ->DriveList->Count; i++) + dprintf(TEXT(" %s\n"), DServ->DriveList->DList[i].Drive); + dprintf(TEXT("\n")); + + dprintf(TEXT(" Shares:\n")); + dprintf(TEXT(" +-------------------+\n")); + for (i = 0; i < DServ->ShareList->Count; i++) + dprintf(TEXT(" %s\n"), DServ->ShareList->SList[i].Name); + dprintf(TEXT("\n")); + +} +#endif + + CursorNormal(); + +} // NTServerInfoSet + + +///////////////////////////////////////////////////////////////////////// +VOID +NTLoginTimesLog( + BYTE *Times + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR *szDays[7]; + DWORD Day; + DWORD Hours; + int Bit = 0; + static TCHAR szHours[80]; + + szDays[0] = Lids(IDS_SUN); + szDays[1] = Lids(IDS_MON); + szDays[2] = Lids(IDS_TUE); + szDays[3] = Lids(IDS_WED); + szDays[4] = Lids(IDS_THU); + szDays[5] = Lids(IDS_FRI); + szDays[6] = Lids(IDS_SAT); + + LogWriteLog(1, Lids(IDS_CRLF)); + LogWriteLog(1, Lids(IDS_L_56)); + + // while these should be indent 2, there isn't room on 80 cols - so indent 1 + LogWriteLog(1, Lids(IDS_L_1)); + LogWriteLog(1, Lids(IDS_L_2)); + LogWriteLog(1, Lids(IDS_L_3)); + + for (Day = 0; Day < 7; Day++) { + LogWriteLog(1, szDays[Day]); + lstrcpy(szHours, TEXT(" ")); + + for (Hours = 0; Hours < 24; Hours++) { + if (BitTest(Bit, Times)) + lstrcat(szHours, TEXT("**")); + else + lstrcat(szHours, TEXT(" ")); + + Bit++; + + lstrcat(szHours, TEXT(" ")); + } + + LogWriteLog(0, szHours); + LogWriteLog(0, Lids(IDS_CRLF)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // NTLoginTimesLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NTUserRecLog( + NT_USER_INFO NT_UInfo + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR tmpStr; + + LogWriteLog(1, Lids(IDS_L_57)); + + LogWriteLog(2, Lids(IDS_L_58), NT_UInfo.full_name); + LogWriteLog(2, Lids(IDS_L_59), NT_UInfo.password); + + switch(NT_UInfo.priv) { + case 0: + tmpStr = Lids(IDS_L_60); + break; + + case 1: + tmpStr = Lids(IDS_L_61); + break; + + case 2: + tmpStr = Lids(IDS_L_62); + break; + } + + LogWriteLog(2, Lids(IDS_L_63), tmpStr); + + LogWriteLog(2, Lids(IDS_L_64), NT_UInfo.home_dir); + LogWriteLog(2, Lids(IDS_L_65), NT_UInfo.comment); + + // Flags + LogWriteLog(2, Lids(IDS_L_66)); + if (NT_UInfo.flags & 0x01) + LogWriteLog(3, Lids(IDS_L_67), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_67), Lids(IDS_NO)); + + if (NT_UInfo.flags & 0x02) + LogWriteLog(3, Lids(IDS_L_68), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_68), Lids(IDS_NO)); + + if (NT_UInfo.flags & 0x04) + LogWriteLog(3, Lids(IDS_L_69), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_69), Lids(IDS_NO)); + + if (NT_UInfo.flags & 0x08) + LogWriteLog(3, Lids(IDS_L_70), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_70), Lids(IDS_NO)); + + if (NT_UInfo.flags & 0x20) + LogWriteLog(3, Lids(IDS_L_71), Lids(IDS_NO)); + else + LogWriteLog(3, Lids(IDS_L_71), Lids(IDS_YES)); + + if (NT_UInfo.flags & 0x40) + LogWriteLog(3, Lids(IDS_L_72), Lids(IDS_NO)); + else + LogWriteLog(3, Lids(IDS_L_72), Lids(IDS_YES)); + + // Script path + LogWriteLog(2, Lids(IDS_L_73), NT_UInfo.script_path); + + LogWriteLog(2, Lids(IDS_L_74), NT_UInfo.full_name); + + LogWriteLog(2, Lids(IDS_L_75), NT_UInfo.logon_server); + + NTLoginTimesLog((BYTE *) NT_UInfo.logon_hours); + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // NTUserRecLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NTDomainSynch( + DEST_SERVER_BUFFER *DServ + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPBYTE buffer = NULL; + BOOL UsePDC = FALSE; + NET_API_STATUS Status; + TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + + wsprintf(LocServer, TEXT("\\\\%s"), DServ->Name); + + if ((DServ->InDomain) && (DServ->Domain != NULL)) { + wsprintf(LocServer, TEXT("\\\\%s"), DServ->Domain->PDCName); + UsePDC = TRUE; + } + + if (UsePDC) + Status = I_NetLogonControl(LocServer, NETLOGON_CONTROL_PDC_REPLICATE, 1, &buffer); + else + Status = I_NetLogonControl(LocServer, NETLOGON_CONTROL_SYNCHRONIZE, 1, &buffer); + + if (buffer != NULL) + NetApiBufferFree(buffer); + +} // NTDomainSynch + + +///////////////////////////////////////////////////////////////////////// +BOOL +NTDomainInSynch( + LPTSTR Server + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + PNETLOGON_INFO_1 buffer = NULL; + NET_API_STATUS Status; + + Status = I_NetLogonControl(Server, NETLOGON_CONTROL_QUERY, 1, (PBYTE *) &buffer); + + if (Status) { + return TRUE; + } + + if (buffer && buffer->netlog1_flags) + return FALSE; + + if (buffer != NULL) + NetApiBufferFree(buffer); + + return TRUE; + +} // NTDomainInSynch + + +///////////////////////////////////////////////////////////////////////// +BOOL +NTDomainGet( + LPTSTR ServerName, + LPTSTR Domain + ) + +/*++ + +Routine Description: + + Gee - what a simple way to get the domain a server is part of! + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR Serv[MAX_SERVER_NAME_LEN + 3]; + UNICODE_STRING us; + NTSTATUS ret; + OBJECT_ATTRIBUTES oa; + ACCESS_MASK am; + SECURITY_QUALITY_OF_SERVICE qos; + LSA_HANDLE hLSA; + PPOLICY_PRIMARY_DOMAIN_INFO pvBuffer; + + if (ServerName[0] == TEXT('\\')) + lstrcpy(Serv, ServerName); + else + wsprintf(Serv, TEXT("\\\\%s"), ServerName); + + // Set up unicode string structure + us.Length = lstrlen(Serv) * sizeof(TCHAR); + us.MaximumLength = us.Length + sizeof(TCHAR); + us.Buffer = Serv; + + // only need read access + am = POLICY_READ | POLICY_VIEW_LOCAL_INFORMATION; + + // set up quality of service + qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + qos.ImpersonationLevel = SecurityImpersonation; + qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; + qos.EffectiveOnly = FALSE; + + // Macro sets everything except security field + InitializeObjectAttributes( &oa, NULL, 0L, NULL, NULL ); + oa.SecurityQualityOfService = &qos; + + ret = LsaOpenPolicy(&us, &oa, am, &hLSA); + + if (!ret) { + ret = LsaQueryInformationPolicy(hLSA, PolicyPrimaryDomainInformation, (PVOID *) &pvBuffer); + LsaClose(hLSA); + if ((!ret) && (pvBuffer != NULL)) { + lstrcpy(Domain, pvBuffer->Name.Buffer); + LsaFreeMemory((PVOID) pvBuffer); + } + } + + if (ret) + return FALSE; + else + return TRUE; + +} // NTDomainGet + + +///////////////////////////////////////////////////////////////////////// +BOOL +IsFPNW( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + Checks the given machine for the FPNW secret. + +Arguments: + + +Return Value: + + +--*/ + +{ + return (FPNWSecretGet(ServerName) != NULL); + +} // IsFPNW + + +///////////////////////////////////////////////////////////////////////// +BOOL +IsNTAS( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + Checks the given machines registry to determine if it is an NTAS + system. The new 'Server' type is also counted as NTAS as all we + use this for is to determine if local or global groups should be + used. + +Arguments: + + +Return Value: + + +--*/ + +{ + HKEY hKey, hKey2; + DWORD dwType, dwSize; + static TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + static TCHAR Type[50]; + LONG Status; + BOOL ret = FALSE; + + wsprintf(LocServer, TEXT("\\\\%s"), ServerName); + + dwSize = sizeof(Type); + if (RegConnectRegistry(LocServer, HKEY_LOCAL_MACHINE, &hKey) == ERROR_SUCCESS) + if ((Status = RegOpenKeyEx(hKey, Lids(IDS_S_12), 0, KEY_READ, &hKey2)) == ERROR_SUCCESS) + if ((Status = RegQueryValueEx(hKey2, Lids(IDS_S_13), NULL, &dwType, (LPBYTE) Type, &dwSize)) == ERROR_SUCCESS) + if (!lstrcmpi(Type, Lids(IDS_S_14))) + ret = TRUE; + + RegCloseKey(hKey); + return ret; + +} // IsNTAS + + +///////////////////////////////////////////////////////////////////////// +VOID +NTTrustedDomainsEnum( + LPTSTR ServerName, + TRUSTED_DOMAIN_LIST **pTList + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR Serv[MAX_SERVER_NAME_LEN + 3]; + TRUSTED_DOMAIN_LIST *TList = NULL; + UNICODE_STRING us; + NTSTATUS ret; + OBJECT_ATTRIBUTES oa; + ACCESS_MASK am; + SECURITY_QUALITY_OF_SERVICE qos; + LSA_HANDLE hLSA; + PPOLICY_PRIMARY_DOMAIN_INFO pvBuffer = NULL; + LSA_ENUMERATION_HANDLE lsaenumh = 0; + LSA_TRUST_INFORMATION *lsat; + ULONG maxrequested = 0xffff; + ULONG cItems; + ULONG i; + + if (ServerName[0] == TEXT('\\')) + lstrcpy(Serv, ServerName); + else + wsprintf(Serv, TEXT("\\\\%s"), ServerName); + + // Set up unicode string structure + us.Length = lstrlen(Serv) * sizeof(TCHAR); + us.MaximumLength = us.Length + sizeof(TCHAR); + us.Buffer = Serv; + + // only need read access + am = POLICY_READ | POLICY_VIEW_LOCAL_INFORMATION; + + // set up quality of service + qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + qos.ImpersonationLevel = SecurityImpersonation; + qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; + qos.EffectiveOnly = FALSE; + + // Macro sets everything except security field + InitializeObjectAttributes( &oa, NULL, 0L, NULL, NULL ); + oa.SecurityQualityOfService = &qos; + + ret = LsaOpenPolicy(&us, &oa, am, &hLSA); + + if (!ret) { + ret = LsaEnumerateTrustedDomains(hLSA, &lsaenumh, (PVOID *) &pvBuffer, maxrequested, &cItems); + LsaClose(hLSA); + if ((!ret) && (pvBuffer != NULL)) { + lsat = (LSA_TRUST_INFORMATION *) pvBuffer; + TList = (TRUSTED_DOMAIN_LIST *) AllocMemory(sizeof(TRUSTED_DOMAIN_LIST) + (cItems * ((MAX_DOMAIN_NAME_LEN + 1) * sizeof(TCHAR)))); + memset(TList, 0, sizeof(TRUSTED_DOMAIN_LIST) + (cItems * ((MAX_DOMAIN_NAME_LEN + 1) * sizeof(TCHAR)))); + + if (TList != NULL) { + TList->Count = cItems; + + for (i = 0; i < cItems; i++) + memcpy(TList->Name[i], lsat[i].Name.Buffer, lsat[i].Name.Length); + } + LsaFreeMemory((PVOID) pvBuffer); + } + } + + *pTList = TList; + +} // NTTrustedDomainsEnum + + +///////////////////////////////////////////////////////////////////////// +DOMAIN_BUFFER * +NTTrustedDomainSet( + HWND hWnd, + LPTSTR Server, + LPTSTR TrustedDomain + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR apiPDCName = NULL; + TCHAR PDCName[MAX_SERVER_NAME_LEN]; + TCHAR LocServer[MAX_SERVER_NAME_LEN + 3]; + static DOMAIN_BUFFER *DBuff; + NET_API_STATUS Status = 0; + + DBuff = NULL; + lstrcpy(PDCName, TEXT("")); + + wsprintf(LocServer, TEXT("\\\\%s"), Server); + Status = NetGetDCName(LocServer, TrustedDomain, (LPBYTE *) &apiPDCName); + + if (!Status) { + // get rid of leading 2 backslashes + if (lstrlen(apiPDCName) > 2) + lstrcpy(PDCName, &apiPDCName[2]); + + if (NTServerValidate(hWnd, PDCName)) { + // Check if we need to add domain to domain list + DBuff = DomainListFind(TrustedDomain); + + if (DBuff == NULL) { + DBuff = DomainListAdd(TrustedDomain, PDCName); + DBuff->Type = ServInfo->sv101_type; + DBuff->VerMaj = ServInfo->sv101_version_major; + DBuff->VerMin = ServInfo->sv101_version_minor; + } + + DBuff->UseCount++; + } // if Domain valid + + if (apiPDCName != NULL) + NetApiBufferFree((LPVOID) apiPDCName); + } + + // make sure we are pointing to the right one + NTServerSet(Server); + return DBuff; + +} // NTTrustedDomainSet + + +///////////////////////////////////////////////////////////////////////// +SID * +NTSIDGet( + LPTSTR ServerName, + LPTSTR pUserName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR lpszDomain[80]; + DWORD dwDomainLength = 80; + + static UCHAR psnuType[1024]; + static SID UserSID[1024]; + DWORD dwSIDBufSize = 1024; + BOOL Retry = TRUE; + + // Get SID for user + while (Retry) { + if (!LookupAccountName(ServerName, pUserName, UserSID, &dwSIDBufSize, + lpszDomain, &dwDomainLength, (PSID_NAME_USE) psnuType)) { +#ifdef DEBUG + dprintf(TEXT("Error %d: LookupAccountName\n"), GetLastError()); +#endif + if (GetLastError() == ERROR_NONE_MAPPED) + if (NTDomainInSynch(ServerName)) + Retry = FALSE; + else + Sleep(5000L); + + } else + return UserSID; + } + + return NULL; + +} // NTSIDGet + + +#define SD_SIZE (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH) + +///////////////////////////////////////////////////////////////////////// +BOOL +NTFile_AccessRightsAdd( + LPTSTR ServerName, + LPTSTR pUserName, + LPTSTR pFileName, + ACCESS_MASK AccessMask, + BOOL Dir + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NTSTATUS ret; + SID *pUserSID; + + // File SD variables + static UCHAR ucSDbuf[SD_SIZE]; + PSECURITY_DESCRIPTOR pFileSD = (PSECURITY_DESCRIPTOR) ucSDbuf; + DWORD dwSDLengthNeeded = 0; + + // New SD variables + UCHAR NewSD[SECURITY_DESCRIPTOR_MIN_LENGTH]; + PSECURITY_DESCRIPTOR psdNewSD=(PSECURITY_DESCRIPTOR)NewSD; + + + // +-----------------------------------------------------------------+ + // | Main Code | + // +-----------------------------------------------------------------+ + pUserSID = NTSIDGet(ServerName, pUserName); + if (pUserSID == NULL) { + LogWriteLog(5, Lids(IDS_L_76), GetLastError()); + ErrorIt(Lids(IDS_L_77), GetLastError(), pUserName); + return FALSE; + } + + // Get security descriptor (SD) for file + if(!GetFileSecurity(pFileName, (SECURITY_INFORMATION) (DACL_SECURITY_INFORMATION), + pFileSD, SD_SIZE, (LPDWORD) &dwSDLengthNeeded)) { +#ifdef DEBUG + dprintf(TEXT("Error %d: GetFileSecurity\n"), GetLastError()); +#endif + LogWriteLog(5, Lids(IDS_L_76), GetLastError()); + ErrorIt(Lids(IDS_L_77), GetLastError(), pUserName); + return (FALSE); + } + + if (Dir) + ret = ACEAdd(pFileSD, pUserSID, AccessMask, DirRightsMapping.NtAceFlags, &psdNewSD ); + else + ret = ACEAdd(pFileSD, pUserSID, AccessMask, FileRightsMapping.NtAceFlags, &psdNewSD ); + + if (ret) { +#ifdef DEBUG + dprintf(TEXT("Error %d: NWAddRight\n"), GetLastError()); +#endif + LogWriteLog(5, Lids(IDS_L_76), GetLastError()); + ErrorIt(Lids(IDS_L_77), GetLastError(), pUserName); + return FALSE; + } + + // Set the SD to the File + if (!SetFileSecurity(pFileName, DACL_SECURITY_INFORMATION, psdNewSD)) { +#ifdef DEBUG + dprintf(TEXT("Error %d: SetFileSecurity\n"), GetLastError()); +#endif + LogWriteLog(5, Lids(IDS_L_76), GetLastError()); + ErrorIt(Lids(IDS_L_77), GetLastError(), pUserName); + + if (psdNewSD != pFileSD) + NW_FREE(psdNewSD); + return FALSE; + } + + // Free the memory allocated for the new ACL, but only if + // it was allocated. + if (psdNewSD != pFileSD) + NW_FREE(psdNewSD); + return TRUE; + +} // NTFile_AccessRightsAdd + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +ACEAdd( + PSECURITY_DESCRIPTOR pSD, + PSID pSid, + ACCESS_MASK AccessMask, + ULONG AceFlags, + PSECURITY_DESCRIPTOR *ppNewSD + ) + +/*++ + +Routine Description: + + ACEAdd() - Taken from ChuckC's NWRights.C + +Arguments: + + psd - The security desciptor to modify. This must be a valid + security descriptor. + + psid - The SID of the user/group for which we are adding this right. + + AccessMask - The access mask that we wish to add. + + ppNewSD - used to return the new Security descriptor. + +Return Value: + + NTSTATUS code + +--*/ + +{ + ACL Acl ; + PACL pAcl, pNewAcl = NULL ; + PACCESS_ALLOWED_ACE pAccessAce, pNewAce = NULL ; + NTSTATUS ntstatus ; + BOOLEAN fDaclPresent, fDaclDefaulted; + BOOLEAN Found = FALSE; + LONG i ; + + // validate and initialize + if (!pSD || !pSid || !ppNewSD || !RtlValidSecurityDescriptor(pSD)) { +#ifdef DEBUG + dprintf(TEXT("ACEAdd: got invalid parm\n")); +#endif + return (STATUS_INVALID_PARAMETER) ; + } + + // if AccessMask == 0, no need to add the ACE + + if( !AccessMask ) { + + *ppNewSD = pSD; + return( STATUS_SUCCESS ); + } + + *ppNewSD = NULL ; + + // extract the DACL from the securiry descriptor + ntstatus = RtlGetDaclSecurityDescriptor(pSD, &fDaclPresent, &pAcl, &fDaclDefaulted) ; + if (!NT_SUCCESS(ntstatus)) { +#ifdef DEBUG + dprintf(TEXT("ACEAdd: RtlGetDaclSecurityDescriptor failed\n")); +#endif + goto CleanupAndExit ; + } + + // if no DACL present, we create one + if ((!fDaclPresent) || (pAcl == NULL)) { + // create Dacl + ntstatus = RtlCreateAcl(&Acl, sizeof(Acl), ACL_REVISION) ; + + if (!NT_SUCCESS(ntstatus)) { +#ifdef DEBUG + dprintf(TEXT("ACEAdd: RtlCreateAcl failed\n")); +#endif + goto CleanupAndExit ; + } + + pAcl = &Acl ; + } + + // loop thru ACEs, looking for entry with the user/group SID + pAccessAce = NULL ; + for (i = 0; i < pAcl->AceCount; i++) { + ACE_HEADER *pAce ; + + ntstatus = RtlGetAce(pAcl,i,&pAce) ; + + if (!NT_SUCCESS(ntstatus)) { +#ifdef DEBUG + dprintf(TEXT("ACEAdd: RtlGetAce failed\n")); +#endif + goto CleanupAndExit ; + } + + if (pAce->AceType == ACCESS_ALLOWED_ACE_TYPE) { + // found a granting ace, which is what we want + PSID pAceSid ; + + pAccessAce = (ACCESS_ALLOWED_ACE *) pAce ; + pAceSid = (PSID) &pAccessAce->SidStart ; + + // + // is this the same SID? + // if yes, modify access mask and carry on. + // + if (RtlEqualSid(pAceSid, pSid)) { + + ACCESS_MASK access_mask ; + + ASSERT(pAccessAce != NULL) ; + + access_mask = pAccessAce->Mask ; + + if ( (access_mask & AccessMask) == access_mask ) { + ntstatus = STATUS_MEMBER_IN_GROUP ; + goto CleanupAndExit ; + } + + pAccessAce->Mask = AccessMask ; + Found = TRUE ; + } + } else { + // ignore it. we only deal with granting aces. + } + } + + if ( !Found ) { // now set the DACL to have the desired rights + // reached end of ACE list without finding match. so we need to + // create a new ACE. + USHORT NewAclSize, NewAceSize ; + + // calculate the sizes + NewAceSize = (USHORT)(sizeof(ACE_HEADER) + + sizeof(ACCESS_MASK) + + RtlLengthSid(pSid)); + + NewAclSize = pAcl->AclSize + NewAceSize ; + + // allocate new ACE and new ACL (since we are growing it) + pNewAce = (PACCESS_ALLOWED_ACE) NW_ALLOC(NewAceSize) ; + if (!pNewAce) { + #ifdef DEBUG + dprintf(TEXT("ACEAdd: memory allocation failed for new ACE\n")); + #endif + ntstatus = STATUS_INSUFFICIENT_RESOURCES ; + goto CleanupAndExit ; + } + + pNewAce->Header.AceFlags = (UCHAR)AceFlags; + pNewAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + pNewAce->Header.AceSize = NewAceSize; + pNewAce->Mask = AccessMask; + RtlCopySid( RtlLengthSid(pSid), (PSID)(&pNewAce->SidStart), pSid ); + + pNewAcl = (PACL) NW_ALLOC(NewAclSize) ; + if (!pNewAcl) { + #ifdef DEBUG + dprintf(TEXT("ACEAdd: memory allocation failed for new ACL\n")); + #endif + ntstatus = STATUS_INSUFFICIENT_RESOURCES ; + goto CleanupAndExit ; + } + + RtlCopyMemory(pNewAcl, pAcl, pAcl->AclSize) ; + pNewAcl->AclSize = NewAclSize ; + + // Add the ACE to the end of the ACL + ntstatus = RtlAddAce(pNewAcl, ACL_REVISION, pNewAcl->AceCount, pNewAce, NewAceSize) ; + + if (!NT_SUCCESS(ntstatus)) { + #ifdef DEBUG + dprintf(TEXT("ACEAdd: RtlAddAce failed\n")); + #endif + goto CleanupAndExit ; + } + + pAcl = pNewAcl ; + } + + + + // set the dacl back into the security descriptor. we need create + // a new security descriptor, since the old one may not have space + // for any additional ACE. + ntstatus = CreateNewSecurityDescriptor(ppNewSD, pSD, pAcl) ; + + if (!NT_SUCCESS(ntstatus)) { +#ifdef DEBUG + dprintf(TEXT("ACEAdd: CreateNewSecurityDescriptor failed\n")); +#endif + } + +CleanupAndExit: + + if (pNewAcl) + NW_FREE(pNewAcl) ; + + if (pNewAce) + NW_FREE(pNewAce) ; + + return ntstatus ; +} // ACEAdd + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +CreateNewSecurityDescriptor( + PSECURITY_DESCRIPTOR *ppNewSD, + PSECURITY_DESCRIPTOR pSD, + PACL pAcl + ) + +/*++ + +Routine Description: + + From a SD and a Dacl, create a new SD. The new SD will be fully self + contained (it is self relative) and does not have pointers to other + structures. + +Arguments: + + ppNewSD - used to return the new SD. Caller should free with NW_FREE + + pSD - the self relative SD we use to build the new SD + + pAcl - the new DACL that will be used for the new SD + +Return Value: + + NTSTATUS code + +--*/ + +{ + PACL pSacl ; + PSID psidGroup, psidOwner ; + BOOLEAN fSaclPresent ; + BOOLEAN fSaclDefaulted, fGroupDefaulted, fOwnerDefaulted ; + ULONG NewSDSize ; + SECURITY_DESCRIPTOR NewSD ; + PSECURITY_DESCRIPTOR pNewSD ; + NTSTATUS ntstatus ; + + + // extract the originals from the securiry descriptor + ntstatus = RtlGetSaclSecurityDescriptor(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlGetOwnerSecurityDescriptor(pSD, &psidOwner, &fOwnerDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlGetGroupSecurityDescriptor(pSD, &psidGroup, &fGroupDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + // now create a new SD and set the info in it. we cannot return this one + // since it has pointers to old SD. + ntstatus = RtlCreateSecurityDescriptor(&NewSD, SECURITY_DESCRIPTOR_REVISION) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlSetDaclSecurityDescriptor(&NewSD, TRUE, pAcl, FALSE) ; + + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlSetSaclSecurityDescriptor(&NewSD, fSaclPresent, pSacl, fSaclDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlSetOwnerSecurityDescriptor(&NewSD, psidOwner, fOwnerDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + ntstatus = RtlSetGroupSecurityDescriptor(&NewSD, psidGroup, fGroupDefaulted) ; + if (!NT_SUCCESS(ntstatus)) + return ntstatus ; + + // calculate size needed for the returned SD and allocated it + NewSDSize = RtlLengthSecurityDescriptor(&NewSD) ; + + pNewSD = (PSECURITY_DESCRIPTOR) NW_ALLOC(NewSDSize) ; + + if (!pNewSD) + return (STATUS_INSUFFICIENT_RESOURCES) ; + + // convert the absolute to self relative + ntstatus = RtlAbsoluteToSelfRelativeSD(&NewSD, pNewSD, &NewSDSize) ; + + if (NT_SUCCESS(ntstatus)) + *ppNewSD = pNewSD ; + else + NW_FREE(pNewSD) ; + + return ntstatus ; +} // CreateNewSecurityDescriptor + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +NTAccessLog( + ACCESS_MASK AccessMask + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR AccessDesc[80]; + TCHAR AccessStr[80]; + + if (AccessMask == 0) { + lstrcpy(AccessDesc, Lids(IDS_L_78)); + return AccessDesc; + } else + if ((AccessMask & GENERIC_ALL) == GENERIC_ALL) { + lstrcpy(AccessDesc, Lids(IDS_L_79)); + return AccessDesc; + } else { + lstrcpy(AccessStr, TEXT("(")); + + if ((AccessMask & GENERIC_READ) == GENERIC_READ) + lstrcat(AccessStr, Lids(IDS_L_80)); + + if ((AccessMask & GENERIC_WRITE) == GENERIC_WRITE) + lstrcat(AccessStr, Lids(IDS_L_81)); + + if ((AccessMask & GENERIC_EXECUTE) == GENERIC_EXECUTE) + lstrcat(AccessStr, Lids(IDS_L_82)); + + if ((AccessMask & DELETE) == DELETE) + lstrcat(AccessStr, Lids(IDS_L_83)); + + if ((AccessMask & WRITE_DAC) == WRITE_DAC) + lstrcat(AccessStr, Lids(IDS_L_84)); + + lstrcat(AccessStr, TEXT(")")); + + // Figured out the individual rights, now need to see if this corresponds + // to a generic mapping + if (!lstrcmpi(AccessStr, Lids(IDS_L_85))) { + lstrcpy(AccessDesc, Lids(IDS_L_86)); + return AccessDesc; + } + + if (!lstrcmpi(AccessStr, Lids(IDS_L_87))) { + lstrcpy(AccessDesc, Lids(IDS_L_88)); + return AccessDesc; + } + + if (!lstrcmpi(AccessStr, Lids(IDS_L_89))) { + lstrcpy(AccessDesc, Lids(IDS_L_90)); + return AccessDesc; + } + + if (!lstrcmpi(AccessStr, Lids(IDS_L_91))) { + lstrcpy(AccessDesc, Lids(IDS_L_92)); + return AccessDesc; + } + + wsprintf(AccessDesc, Lids(IDS_L_93), AccessStr); + } + + return AccessDesc; + +} // NTAccessLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NTUserDefaultsGet( + NT_DEFAULTS **UDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + USER_MODALS_INFO_0 *NTDefaults = NULL; + NET_API_STATUS Status = 0; + + if (LocalMachine) + Status = NetUserModalsGet(NULL, 0, (LPBYTE *) &NTDefaults); + else + Status = NetUserModalsGet(CachedServer, 0, (LPBYTE *) &NTDefaults); + + if (Status) { + NTDefaults = NULL; + return; + } + + *UDefaults = (NT_DEFAULTS *) NTDefaults; +} // NTUserDefaultsGet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NTUserDefaultsSet( + NT_DEFAULTS NTDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NET_API_STATUS Status = 0; + DWORD err; + + if (LocalMachine) + Status = NetUserModalsSet(NULL, 0, (LPBYTE) &NTDefaults, &err); + else + Status = NetUserModalsSet(CachedServer, 0, (LPBYTE) &NTDefaults, &err); + + return Status; + +} // NTUserDefaultsSet + + +///////////////////////////////////////////////////////////////////////// +VOID +NTUserDefaultsLog( + NT_DEFAULTS UDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LogWriteLog(1, Lids(IDS_L_94), UDefaults.min_passwd_len); + + // Age is in seconds, convert to days + LogWriteLog(1, Lids(IDS_L_95), UDefaults.max_passwd_age / 86400); + LogWriteLog(1, Lids(IDS_L_96), UDefaults.force_logoff); + LogWriteLog(0, Lids(IDS_CRLF)); +} // NTUserDefaultsLog diff --git a/private/nw/convert/nwconv/ntnetapi.h b/private/nw/convert/nwconv/ntnetapi.h new file mode 100644 index 000000000..b2e3c6da6 --- /dev/null +++ b/private/nw/convert/nwconv/ntnetapi.h @@ -0,0 +1,85 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HNTNETAPI_ +#define _HNTNETAPI_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef NTSTATUS +typedef LONG NTSTATUS; +#endif + +DWORD NTSAMConnect(LPTSTR FileServer, LPTSTR DomainName); +void NTSAMClose(); +DWORD NTSAMParmsSet(LPTSTR ObjectName, FPNW_INFO fpnw, LPTSTR Password, BOOL ForcePasswordChange); +DWORD NTObjectIDGet( LPTSTR ObjectName ); + +DWORD NTShareAdd(LPTSTR ShareName, LPTSTR Path); +DWORD FPNWShareAdd(LPTSTR ShareName, LPTSTR Path); +void NTUseDel(LPTSTR ServerName); + +DWORD NTServerEnum(LPTSTR Container, SERVER_BROWSE_LIST **ServList); +DWORD NTDomainEnum(SERVER_BROWSE_LIST **lpServList); +DWORD NTGroupsEnum(GROUP_LIST **lpGroupList); +DWORD NTUsersEnum(USER_LIST **lpUserList); + +DWORD NTGroupSave(LPTSTR Name); +DWORD NTUserInfoSave(NT_USER_INFO *NT_UInfo, PFPNW_INFO fpnw); +void NTServerInfoReset(HWND hWnd, DEST_SERVER_BUFFER *DServ, BOOL ResetDomain); +DWORD NTUserInfoSet(NT_USER_INFO *NT_UInfo, PFPNW_INFO fpnw); +DWORD NTGroupUserAdd(LPTSTR GroupName, LPTSTR UserName, BOOL Local); + +void NTUserRecInit(LPTSTR UserName, NT_USER_INFO *NT_UInfo); +void NTUserRecLog(NT_USER_INFO NT_UInfo); + +DWORD NTSharesEnum(SHARE_LIST **lpShares, DRIVE_LIST *Drives); + +void NTUseDel(LPTSTR ServerName); +void NTConnListDeleteAll(); + +DWORD NTServerSet(LPTSTR FileServer); +void NTServerInfoSet(HWND hWnd, LPTSTR ServerName, DEST_SERVER_BUFFER *DServ); +BOOL NTServerValidate(HWND hWnd, LPTSTR ServerName); +void NTServerGetInfo(LPTSTR ServerName); +void NTDomainSynch(DEST_SERVER_BUFFER *DServ); +BOOL NTDomainInSynch(LPTSTR Server); + +// #define these so they can be changed easily. these macros +// should be used to free the memory allocated by the routines in +// this module. +#define NW_ALLOC(x) ((LPBYTE)LocalAlloc(LPTR,x)) +#define NW_FREE(p) ((void)LocalFree((HLOCAL)p)) + + +NTSTATUS NwAddRight( PSECURITY_DESCRIPTOR pSD, PSID pSid, ACCESS_MASK AccessMask, PSECURITY_DESCRIPTOR *ppNewSD ) ; +NTSTATUS CreateNewSecurityDescriptor( PSECURITY_DESCRIPTOR *ppNewSD, PSECURITY_DESCRIPTOR pSD, PACL pAcl) ; + +typedef struct _TRUSTED_DOMAIN_LIST { + ULONG Count; + TCHAR Name[][MAX_DOMAIN_NAME_LEN + 1]; +} TRUSTED_DOMAIN_LIST; + + +BOOL NTDomainGet(LPTSTR ServerName, LPTSTR Domain); +BOOL IsNTAS(LPTSTR Server); +void NTTrustedDomainsEnum(LPTSTR ServerName, TRUSTED_DOMAIN_LIST **pTList); +DOMAIN_BUFFER *NTTrustedDomainSet(HWND hWnd, LPTSTR Server, LPTSTR TrustedDomain); + +SID *NTSIDGet(LPTSTR ServerName, LPTSTR pUserName); +BOOL NTFile_AccessRightsAdd(LPTSTR ServerName, LPTSTR pUserName, LPTSTR pFileName, ACCESS_MASK AccessMask, BOOL Dir); +LPTSTR NTAccessLog(ACCESS_MASK AccessMask); + +void NTUserDefaultsGet(NT_DEFAULTS **UDefaults); +DWORD NTUserDefaultsSet(NT_DEFAULTS UDefaults); +void NTUserDefaultsLog(NT_DEFAULTS UDefaults); +BOOL IsFPNW(LPTSTR ServerName); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/ntsecapi.h b/private/nw/convert/nwconv/ntsecapi.h new file mode 100644 index 000000000..9db3fedcd --- /dev/null +++ b/private/nw/convert/nwconv/ntsecapi.h @@ -0,0 +1,28 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _NTSECAPI_ +#define _NTSECAPI_ + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef struct _TRUSTED_DOMAIN_LIST { + ULONG Count; + TCHAR Name[][MAX_DOMAIN_NAME_LEN + 1]; +} TRUSTED_DOMAIN_LIST; + + +BOOL NTDomainGet(LPTSTR ServerName, LPTSTR Domain); +BOOL IsNTAS(LPTSTR Server); +void NTTrustedDomainsEnum(LPTSTR ServerName, TRUSTED_DOMAIN_LIST **pTList); +SID *NTSIDGet(LPTSTR ServerName, LPTSTR pUserName); +BOOL NTFile_AccessRightsAdd(LPTSTR ServerName, LPTSTR pUserName, LPTSTR pFileName, ULONG Rights, BOOL Dir); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/nwconv.c b/private/nw/convert/nwconv/nwconv.c new file mode 100644 index 000000000..a0dbcbbaa --- /dev/null +++ b/private/nw/convert/nwconv/nwconv.c @@ -0,0 +1,1509 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + nwconv.c + +Abstract: + + +Author: + + Arthur Hanson (arth) 16-Jun-1994 + +Revision History: + +--*/ + + +#include "globals.h" + +#include "nwconv.h" +#include "convapi.h" +#include "userdlg.h" +#include "filedlg.h" +#include "transfer.h" +#include "columnlb.h" +#include "ntnetapi.h" +#include "nwnetapi.h" + +HINSTANCE hInst; // current instance + +TCHAR szAppName[] = TEXT("NWConv"); // The name of this application +TCHAR ProgPath[MAX_PATH + 1]; + +TCHAR NT_PROVIDER[60]; +TCHAR NW_PROVIDER[60]; +TCHAR NW_SERVICE_NAME[80]; + +#define DEF_CONFIG_FILE TEXT("NWConv.DAT") + +// version as x.yz expressed as xyz (no decimal point). +#define CONFIG_VER 026 +#define CHECK_CONST 0xA5A56572 + +SOURCE_SERVER_BUFFER *lpSourceServer; +DEST_SERVER_BUFFER *lpDestServer; + +BOOL TrialConversion = TRUE; +BOOL IsNetWareBrowse; +BOOL FirstTime = TRUE; +HICON MyIcon; +UINT NumServerPairs = 0; +HWND hDlgMain; + +HHOOK hhkMsgFilter = NULL; +UINT wHelpMessage; + +UINT uMenuID; +HMENU hMenu; +UINT uMenuFlags; + +#ifdef DEBUG +int DebugFlag = 0; +#endif + +CONVERT_LIST *ConvertListStart = NULL; +CONVERT_LIST *ConvertListEnd = NULL; +CONVERT_LIST *CurrentConvertList = NULL; +int TotalConvertCount = 0; + +SOURCE_SERVER_BUFFER *SServListStart = NULL; +SOURCE_SERVER_BUFFER *SServListEnd = NULL; +SOURCE_SERVER_BUFFER *SServListCurrent = NULL; +DEST_SERVER_BUFFER *DServListStart = NULL; +DEST_SERVER_BUFFER *DServListEnd = NULL; +DEST_SERVER_BUFFER *DServListCurrent = NULL; +DOMAIN_BUFFER *DomainListStart = NULL; +DOMAIN_BUFFER *DomainListEnd = NULL; + +BOOL SuccessfulConversion = FALSE; +BOOL ViewLogs = FALSE; +BOOL InConversion = FALSE; + +/*+-------------------------------------------------------------------------+ + | Function Prototypes. | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgUsers(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK DlgMoveIt(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +VOID AboutBox_Do(HWND hDlg); +VOID ToggleControls(HWND hDlg, BOOL Toggle); + + +///////////////////////////////////////////////////////////////////////// +VOID NTServInfoDlg_SwitchControls( + HWND hDlg, + BOOL Toggle + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + HWND hCtrl; + + // The NW Controls + hCtrl = GetDlgItem(hDlg, IDC_T_VOLUMES); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_LIST3); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, Toggle); + + // The NT Controls + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + ShowWindow(hCtrl, !Toggle); + EnableWindow(hCtrl, !Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_LIST2); + ShowWindow(hCtrl, !Toggle); + EnableWindow(hCtrl, !Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_T_DRIVES); + ShowWindow(hCtrl, !Toggle); + EnableWindow(hCtrl, !Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_T_SHARES); + ShowWindow(hCtrl, !Toggle); + EnableWindow(hCtrl, !Toggle); + +} // NTServInfoDlg_SwitchControls + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServInfoDlg_EnableNT( + HWND hDlg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR VerStr[TMP_STR_LEN_256]; + + SetDlgItemText(hDlg, IDC_TYPE, Lids(IDS_S_15)); + wsprintf(VerStr, TEXT("%lu.%lu"), CurrentConvertList->FileServ->VerMaj, CurrentConvertList->FileServ->VerMin); + SetDlgItemText(hDlg, IDC_VERSION, VerStr); + + NTServInfoDlg_SwitchControls(hDlg, FALSE); + +} // NTServInfoDlg_EnableNT + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServInfoDlg_EnableNW( + HWND hDlg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR VerStr[TMP_STR_LEN_256]; + + SetDlgItemText(hDlg, IDC_TYPE, Lids(IDS_S_16)); + wsprintf(VerStr, TEXT("%u.%u"), CurrentConvertList->SourceServ->VerMaj, CurrentConvertList->SourceServ->VerMin); + SetDlgItemText(hDlg, IDC_VERSION, VerStr); + + NTServInfoDlg_SwitchControls(hDlg, TRUE); + +} // NTServInfoDlg_EnableNW + + +///////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK +NTServInfoDlg( + HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR AddLine[TMP_STR_LEN_256]; + HWND hCtrl; + DWORD dwData, dwIndex; + int wmId, wmEvent; + ULONG i; + DRIVE_LIST *DriveList; + SHARE_LIST *ShareList; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // Add the servers to the combo-box and select the source server + hCtrl = GetDlgItem(hDlg, IDC_COMBO1); + dwIndex = SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) CurrentConvertList->FileServ->Name); + SendMessage(hCtrl, CB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) CurrentConvertList->FileServ); + dwIndex = SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) CurrentConvertList->SourceServ->Name); + SendMessage(hCtrl, CB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) CurrentConvertList->SourceServ); + + SendMessage(hCtrl, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) CurrentConvertList->SourceServ->Name); + + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + EndDialog(hDlg, 0); + return (TRUE); + break; + + case ID_INIT: + // Fill in the Drive and share lists for NT system + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + DriveList = CurrentConvertList->FileServ->DriveList; + if (DriveList != NULL) { + for (i = 0; i < DriveList->Count; i++) { + wsprintf(AddLine, TEXT("%s: [%4s] %s"), DriveList->DList[i].Drive, DriveList->DList[i].DriveType, DriveList->DList[i].Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + + wsprintf(AddLine, Lids(IDS_S_17), lToStr(DriveList->DList[i].FreeSpace)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } + + hCtrl = GetDlgItem(hDlg, IDC_LIST2); + ShareList = CurrentConvertList->FileServ->ShareList; + if (ShareList != NULL) + for (i = 0; i < ShareList->Count; i++) { + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) ShareList->SList[i].Name); + wsprintf(AddLine, Lids(IDS_S_18), ShareList->SList[i].Path); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + + + hCtrl = GetDlgItem(hDlg, IDC_LIST3); + ShareList = CurrentConvertList->SourceServ->ShareList; + if (ShareList != NULL) + for (i = 0; i < ShareList->Count; i++) { + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) ShareList->SList[i].Name); + wsprintf(AddLine, Lids(IDS_S_19), lToStr(ShareList->SList[i].Size)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + + + PostMessage(hDlg, WM_COMMAND, ID_UPDATECOMBO, 0L); + break; + + case ID_UPDATECOMBO: + hCtrl = GetDlgItem(hDlg, IDC_COMBO1); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0L); + + if (dwIndex != CB_ERR) { + dwData = SendMessage(hCtrl, CB_GETITEMDATA, dwIndex, 0L); + if (dwData == (DWORD) CurrentConvertList->FileServ) + NTServInfoDlg_EnableNT(hDlg); + + if (dwData == (DWORD) CurrentConvertList->SourceServ) + NTServInfoDlg_EnableNW(hDlg); + + } + break; + + case IDC_COMBO1: + if (wmEvent == CBN_SELCHANGE) + PostMessage(hDlg, WM_COMMAND, ID_UPDATECOMBO, 0L); + + break; + + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // NTServInfoDlg + + +///////////////////////////////////////////////////////////////////////// +VOID +NTServInfoDlg_Do( + HWND hDlg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC)NTServInfoDlg, hInst); + DialogBox(hInst, TEXT("NTServInfo"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // NTServInfoDlg_Do + + +///////////////////////////////////////////////////////////////////////// +VOID +MainListbox_Add( + HWND hDlg, + DWORD Data, + LPTSTR SourceServ, + LPTSTR DestServ + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR AddLine[256]; + CONVERT_LIST *ptr; + CONVERT_LIST *nptr = NULL; + DWORD dwData, ret; + DWORD wItemNum = 0; + HWND hCtrl; + BOOL match = FALSE; + ULONG nPairs; + + // We want to insert this after any any other conversion to this source + // machine - unfortuantly it is cumbersome to do this. + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + + // start count at one less as it will always be one ahead of us + nPairs = SendMessage(hCtrl, LB_GETCOUNT, 0, 0L); + + // Try to find a matching destination server for this in the listbox + ptr = (CONVERT_LIST *) Data; + while((wItemNum < nPairs) && !match) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + if (dwData != LB_ERR) { + nptr = (CONVERT_LIST *) dwData; + if (!lstrcmpi(ptr->FileServ->Name, nptr->FileServ->Name)) + match = TRUE; + } + + if (!match) + wItemNum++; + } + + if (match) { + // have a match - so go to the end of the matching servers... + while((wItemNum < nPairs) && match) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + if (dwData != LB_ERR) { + nptr = (CONVERT_LIST *) dwData; + if (lstrcmpi(ptr->FileServ->Name, nptr->FileServ->Name)) + match = FALSE; + } + + if (match) + wItemNum++; + } + + } else { + if (ptr->FileServ->InDomain && ptr->FileServ->Domain) { + wItemNum = 0; + + // No matching servers, so try to find matching domain + while((wItemNum < nPairs) && !match) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + if (dwData != LB_ERR) { + nptr = (CONVERT_LIST *) dwData; + + if (nptr->FileServ->InDomain && nptr->FileServ->Domain) + if (!lstrcmpi(ptr->FileServ->Domain->Name, nptr->FileServ->Domain->Name)) + match = TRUE; + } + + if (!match) + wItemNum++; + } + + if (match) { + // have a match - so go to the end of the matching domain... + while((wItemNum < nPairs) && match) { + dwData = ColumnLB_GetItemData(hCtrl, wItemNum); + if (dwData != LB_ERR) { + nptr = (CONVERT_LIST *) dwData; + + if (nptr->FileServ->InDomain && nptr->FileServ->Domain) { + if (lstrcmpi(ptr->FileServ->Domain->Name, nptr->FileServ->Domain->Name)) + match = FALSE; + } else + match = FALSE; + } + + if (match) + wItemNum++; + } + } + } // if domain + } + + wsprintf(AddLine, TEXT("%s\t%s\t"), SourceServ, DestServ); + + wItemNum = ColumnLB_InsertString(hCtrl, wItemNum, AddLine); + ret = ColumnLB_SetItemData(hCtrl, wItemNum, Data); + ColumnLB_SetCurSel(hCtrl, wItemNum); + +} // MainListbox_Add + + +///////////////////////////////////////////////////////////////////////// +VOID +ConfigurationReset( + HWND hDlg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + // Remove the listbox entries + ColumnLB_ResetContent(GetDlgItem(hDlg, IDC_LIST1)); + + ToggleControls(hDlg, FALSE); + SetFocus(GetDlgItem(hDlg, IDC_ADD)); + + ConvertListDeleteAll(); + UserOptionsDefaultsReset(); + FileOptionsDefaultsReset(); + LogOptionsInit(); + +} // ConfigurationReset + + +///////////////////////////////////////////////////////////////////////// +VOID +ConfigurationSave( + LPTSTR FileName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD wrote; + HANDLE hFile; + CHAR FileNameA[MAX_PATH + 1]; + DWORD Check, Ver; + + WideCharToMultiByte(CP_ACP, 0, FileName, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + + // Create it no matter what + hFile = CreateFileA( FileNameA, GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile != INVALID_HANDLE_VALUE) { + // Save out our check value and the version info + Check = CHECK_CONST; + WriteFile(hFile, &Check, sizeof(Check), &wrote, NULL); + Ver = CONFIG_VER; + WriteFile(hFile, &Ver, sizeof(Ver), &wrote, NULL); + + // Save global log file options + LogOptionsSave(hFile); + + // Save out convert Lists + ConvertListSaveAll(hFile); + + } + + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + + return; + +} // ConfigurationSave + + +///////////////////////////////////////////////////////////////////////// +VOID +ConfigurationLoad( + HWND hDlg, + LPTSTR FileName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR AddLine[256]; + DWORD wrote; + HANDLE hFile; + CHAR FileNameA[MAX_PATH + 1]; + DWORD Check, Ver; + + WideCharToMultiByte(CP_ACP, 0, FileName, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + + // Open, but fail if already exists. + hFile = CreateFileA( FileNameA, GENERIC_READ, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile != INVALID_HANDLE_VALUE) { + ConfigurationReset(hDlg); + ReadFile(hFile, &Check, sizeof(Check), &wrote, NULL); + + if (Check != CHECK_CONST) { + CloseHandle(hFile); + ErrorBox(Lids(IDS_E_10)); + return; + } + + ReadFile(hFile, &Ver, sizeof(Ver), &wrote, NULL); + + if (Ver != CONFIG_VER) { + CloseHandle(hFile); + ErrorBox(Lids(IDS_E_11)); + return; + } + + LogOptionsLoad(hFile); + + // Load in convert list and all associated info... + ConvertListLoadAll(hFile); + + // Everything from the file is loaded in - but now the painful part + // begins. We need to take the following steps: + // + // 1. Walk all lists and refix pointers from their index + // 2. Re-Validate servers, shares, domains, etc. to make sure they + // haven't changed underneath us since we saved out the file. + // 3. Re-create info that wasn't saved out (like drive lists). + + // 1. Walk and refix lists + ConvertListFixup(hDlg); + + // Now add them to the listbox + CurrentConvertList = ConvertListStart; + while (CurrentConvertList) { + MainListbox_Add(hDlg, (DWORD) CurrentConvertList, CurrentConvertList->SourceServ->Name, CurrentConvertList->FileServ->Name); + CurrentConvertList = CurrentConvertList->next; + } + + // Re-enable all the toggles + if (NumServerPairs) + PostMessage(hDlg, WM_COMMAND, (WPARAM) IDM_ADDSEL, 0); + + } + + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + + return; + +} // ConfigurationLoad + + +///////////////////////////////////////////////////////////////////////// +VOID +CanonServerName( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR TmpStr = ServerName; + + while (*TmpStr == TEXT('\\')) + TmpStr++; + + lstrcpy(ServerName, TmpStr); + +} // CanonServerName + + +///////////////////////////////////////////////////////////////////////// +int +MessageFilter( + INT nCode, + WPARAM wParam, + LPMSG lpMsg + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + if (nCode < 0) + goto DefHook; + + if (nCode == MSGF_MENU) { + + if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) { + // Window of menu we want help for is in loword of lParam. + + PostMessage(hDlgMain, wHelpMessage, MSGF_MENU, (LPARAM)lpMsg->hwnd); + return 1; + } + + } + else + if (nCode == MSGF_DIALOGBOX) { + + if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) { + // Dialog box we want help for is in loword of lParam + + PostMessage(hDlgMain, wHelpMessage, MSGF_DIALOGBOX, (LPARAM)lpMsg->hwnd); + return 1; + } + + } else + +DefHook: + return (INT)DefHookProc(nCode, wParam, (DWORD)lpMsg, &hhkMsgFilter); + + return 0; +} // MessageFilter + + +///////////////////////////////////////////////////////////////////////// +int APIENTRY +WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + LPTSTR ptr; + DLGPROC lpproc; + HACCEL haccel; + MSG msg; + + hInst = hInstance; + + if (!hPrevInstance) { + BookTab_Initialize(hInst); + ColumnLBClass_Register(hInst); + } + + MultiByteToWideChar(CP_ACP, 0, _pgmptr, -1, ProgPath, sizeof(ProgPath) ); + + // go to the end and rewind to remove program name + ptr = ProgPath; + while (*ptr) + ptr++; + + while (*ptr != TEXT('\\')) + ptr--; + + ptr++; + + *ptr = TEXT('\0'); + + MemInit(); + MyIcon = LoadIcon(hInst, szAppName); + + lpproc = MakeProcInstance((DLGPROC) DlgMoveIt, hInst); + hDlgMain = CreateDialog(hInst, szAppName, NULL, lpproc); + wHelpMessage = RegisterWindowMessage(TEXT("ShellHelp")); + haccel = LoadAccelerators(hInst, TEXT("MainAcc")); + hhkMsgFilter = SetWindowsHook(WH_MSGFILTER, (HOOKPROC)MessageFilter); + + while (GetMessage(&msg, NULL, 0, 0)) { + if (!TranslateAccelerator(hDlgMain, haccel, &msg)) + if ((hDlgMain == 0) || !IsDialogMessage(hDlgMain, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + FreeProcInstance(lpproc); + + ColumnLBClass_Unregister(hInst); + DestroyIcon(MyIcon); + StringTableDestroy(); + + return msg.wParam; + +} // WinMain + + +///////////////////////////////////////////////////////////////////////// +VOID +ToggleControls( + HWND hDlg, + BOOL Toggle + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_TRIAL); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_DELETE); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_USERINF); + EnableWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_FILEINF); + EnableWindow(hCtrl, Toggle); + +} // ToggleControls + + +///////////////////////////////////////////////////////////////////////// +DWORD +ConfigFileGet( + HWND hwnd + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + OPENFILENAME ofn; + TCHAR szDirName[MAX_PATH+1]; + TCHAR szFile[256], szFileTitle[256]; + UINT i, cbString; + TCHAR chReplace; + TCHAR szFilter[256]; + LPTSTR szExt = TEXT("CNF"); + + lstrcpy(szDirName, ProgPath); + lstrcpy(szFile, TEXT("")); + + if ((cbString = LoadString(hInst, IDS_MAINFILTERSTRING, szFilter, sizeof(szFilter))) == 0) { + // Error occured + return 1L; + } + + chReplace = szFilter[cbString - 1]; // Retrieve wild character + + for (i = 0; szFilter[i] != TEXT('\0'); i++) { + if (szFilter[i] == chReplace) + szFilter[i] = TEXT('\0'); + } + + // Set all structure members to zero + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrDefExt = szExt; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; + + if (GetOpenFileName(&ofn)) { + // Load the configuration + ConfigurationLoad(hwnd, ofn.lpstrFile); + return 0L; + } else { + // Couldn't open the dang file + return 1L; + } + +} // ConfigFileGet + + +///////////////////////////////////////////////////////////////////////// +DWORD +ConfigFileSave( + HWND hwnd + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + OPENFILENAME ofn; + TCHAR szDirName[MAX_PATH + 1]; + TCHAR szFile[MAX_PATH + 1], szFileTitle[MAX_PATH + 1]; + UINT i, cbString; + TCHAR chReplace; + TCHAR szFilter[256]; + LPTSTR szExt; + + szExt = Lids(IDS_S_20); + + lstrcpy(szDirName, ProgPath); + lstrcpy(szFile, TEXT("")); + + if ((cbString = LoadString(hInst, IDS_MAINFILTERSTRING, szFilter, sizeof(szFilter))) == 0) { + // Error occured + return 1L; + } + + chReplace = szFilter[cbString - 1]; // Retrieve wild character + + for (i = 0; szFilter[i] != TEXT('\0'); i++) { + if (szFilter[i] == chReplace) + szFilter[i] = TEXT('\0'); + } + + // Set all structure members to zero + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrDefExt = szExt; + ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + + if (GetSaveFileName(&ofn)) { + // Save Configuration + ConfigurationSave( ofn.lpstrFile); + return 0L; + } else { + // Couldn't save it + return 1L; + } + +} // ConfigFileSave + + +///////////////////////////////////////////////////////////////////////// +BOOL +ProvidersInit() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + HKEY hKey; + DWORD dwType, dwSize; + LONG Status; + BOOL ret = FALSE; + + dwSize = sizeof(NW_PROVIDER); + if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Lids(IDS_S_23), 0, KEY_READ, &hKey)) == ERROR_SUCCESS) + if ((Status = RegQueryValueEx(hKey, Lids(IDS_S_21), NULL, &dwType, (LPBYTE) NW_PROVIDER, &dwSize)) == ERROR_SUCCESS) + ret = TRUE; + + RegCloseKey(hKey); + + if (ret) { + ret = FALSE; + hKey = 0; + dwSize = sizeof(NT_PROVIDER); + if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Lids(IDS_S_25), 0, KEY_READ, &hKey)) == ERROR_SUCCESS) + if ((Status = RegQueryValueEx(hKey, Lids(IDS_S_21), NULL, &dwType, (LPBYTE) NT_PROVIDER, &dwSize)) == ERROR_SUCCESS) + ret = TRUE; + + RegCloseKey(hKey); + } + + if (ret) { + ret = FALSE; + hKey = 0; + dwSize = sizeof(NW_SERVICE_NAME); + if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Lids(IDS_S_24), 0, KEY_READ, &hKey)) == ERROR_SUCCESS) + if ((Status = RegQueryValueEx(hKey, Lids(IDS_S_22), NULL, &dwType, (LPBYTE) Lids(IDS_S_24), &dwSize)) == ERROR_SUCCESS) + ret = TRUE; + + RegCloseKey(hKey); + } + + return ret; + +} // ProvidersInit + + +///////////////////////////////////////////////////////////////////////// +BOOL +CheckServiceInstall() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + SC_HANDLE hSC; + DWORD dwBytesNeeded, dwNumEntries, dwhResume; + ENUM_SERVICE_STATUS *lpStatus = NULL; + BOOL ret = FALSE; + + if (!ProvidersInit()) + return FALSE; + + // initialize variables for enumeration... + dwBytesNeeded = dwNumEntries = dwhResume = 0; + + // acquire handle to svc controller to query for netware client... + if (hSC = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE)) { + + UINT i; + LPTSTR lpServiceName = Lids(IDS_S_26); // NWCWorkstation + + // ask for buffer size... + ret = EnumServicesStatus( + hSC, + SERVICE_WIN32, + SERVICE_ACTIVE, + NULL, + 0, + &dwBytesNeeded, + &dwNumEntries, + &dwhResume + ); + + // intentionally called function with no buffer to size... + if ((ret == FALSE) && (GetLastError() == ERROR_MORE_DATA)) { + + // allocate buffer with size passed back... + if (lpStatus = AllocMemory(dwBytesNeeded)) { + + // ask for svc entries... + if (EnumServicesStatus( + hSC, + SERVICE_WIN32, + SERVICE_ACTIVE, + lpStatus, + dwBytesNeeded, + &dwBytesNeeded, + &dwNumEntries, + &dwhResume)) { + + // search service names for match... + for (i = 0; ((i < dwNumEntries) && (ret == FALSE)); i++) { + if (!lstrcmpi(lpStatus[i].lpServiceName, lpServiceName)) { + ret = TRUE; // found it... + } + } + } + + FreeMemory(lpStatus); + } + } + + CloseServiceHandle(hSC); + } + + return ret; + +} // CheckServiceInstall + + +///////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK +DlgMoveIt( + HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR AddLine[256]; + int wmId, wmEvent; + HWND hCtrl; + PAINTSTRUCT ps; + HDC hDC; + RECT rc; + DWORD Index; + DWORD dwData; + int TabStop; + + switch (message) { + case WM_INITDIALOG: + + ConvertListStart = ConvertListEnd = NULL; + UserOptionsDefaultsReset(); + FileOptionsDefaultsReset(); + LogOptionsInit(); + + // Disable controls until server pair is choosen... + ToggleControls(hDlg, FALSE); + + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + GetClientRect(hCtrl, &rc); + + // Size is half width of listbox - vertical scrollbar + TabStop = (((rc.right - rc.left) - GetSystemMetrics(SM_CXVSCROLL)) / 2); + ColumnLB_SetNumberCols(hCtrl, 2); + ColumnLB_SetColTitle(hCtrl, 0, Lids(IDS_D_11)); + ColumnLB_SetColTitle(hCtrl, 1, Lids(IDS_D_12)); + ColumnLB_SetColWidth(hCtrl, 0, TabStop); + // Calculate 2nd this way instead of just TabStop to get rid of roundoff + ColumnLB_SetColWidth(hCtrl, 1, (rc.right - rc.left) - TabStop); + + // This is needed as otherwise only the Add box will display - weird... + ShowWindow(hDlg, SW_SHOWNORMAL); + + // Check if NWCS is installed + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L); + + break; + + case WM_ERASEBKGND: + + // Process so icon background isn't painted grey - main dlg + // can't be DS_MODALFRAME either, or else a frame is painted around + // the icon. + if (IsIconic(hDlg)) + return TRUE; + + break; + + case WM_DESTROY: + NTConnListDeleteAll(); + PostQuitMessage(0); + break; + + case WM_PAINT: + hDC = BeginPaint(hDlg, &ps); + if (IsIconic(hDlg)) { + GetClientRect(hDlg, &rc); + DrawIcon(hDC, rc.left, rc.top, MyIcon); + } + + EndPaint(hDlg, &ps); + break; + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + // If we are currently doing a conversion then get out + if (InConversion) + break; + + switch (wmId) { + case IDOK: + InConversion = TRUE; + DoConversion(hDlg, FALSE); + InConversion = FALSE; + + if (ConversionSuccessful()) { + ConfigurationReset(hDlg); + DeleteFile(DEF_CONFIG_FILE); + } + + break; + + case ID_INIT: + CursorHourGlass(); + if (!CheckServiceInstall()) { + CursorNormal(); + WarningError(Lids(IDS_E_12)); + PostMessage(hDlg, WM_DESTROY, 0, 0); + } else { + + ConfigurationLoad(hDlg, DEF_CONFIG_FILE); + CursorNormal(); + + if (!NumServerPairs) { + // Put up the add dialog box + if (FirstTime) { + FirstTime = FALSE; + PostMessage(hDlg, WM_COMMAND, IDC_ADD, 0); + } + } + + } + + break; + + case IDC_TRIAL: + InConversion = TRUE; + DoConversion(hDlg, TRUE); + InConversion = FALSE; + break; + + case IDCANCEL: + case IDC_EXIT: + CursorHourGlass(); + + if (NumServerPairs) + ConfigurationSave(DEF_CONFIG_FILE); + else { + DeleteFile(DEF_CONFIG_FILE); + } + + ConfigurationReset(hDlg); + CursorNormal(); + PostMessage(hDlg, WM_DESTROY, 0, 0); + break; + + case ID_FILE_OPEN: + ConfigFileGet(hDlg); + break; + + case ID_FILE_SAVE: + ConfigFileSave(hDlg); + break; + + case ID_FILE_DEFAULT: + if (MessageBox(hDlg, Lids(IDS_RESTOREDEFAULTS), Lids(IDS_TXTWARNING), MB_OKCANCEL | MB_ICONEXCLAMATION) == IDOK) { + // Remove the listbox entries + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + ColumnLB_ResetContent(hCtrl); + + ToggleControls(hDlg, FALSE); + + ConvertListDeleteAll(); + UserOptionsDefaultsReset(); + FileOptionsDefaultsReset(); + ViewLogs = FALSE; + } + break; + + case ID_LOGGING: + DoLoggingDlg(hDlg); + return TRUE; + + break; + + case IDC_USERINF: + // Figure out which server pair is selected and pass server pair to user config dialog + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + Index = ColumnLB_GetCurSel(hCtrl); + dwData = ColumnLB_GetItemData(hCtrl, Index); + CurrentConvertList = (CONVERT_LIST *) dwData; + + UserOptions_Do(hDlg, CurrentConvertList->ConvertOptions, CurrentConvertList->SourceServ, CurrentConvertList->FileServ); + return TRUE; + + case IDC_FILEINF: + // Figure out which server pair is selected and pass server pair to file config dialog + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + Index = ColumnLB_GetCurSel(hCtrl); + dwData = ColumnLB_GetItemData(hCtrl, Index); + CurrentConvertList = (CONVERT_LIST *) dwData; + + FileOptions_Do(hDlg, CurrentConvertList->FileOptions, CurrentConvertList->SourceServ, CurrentConvertList->FileServ); + break; + + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_MAIN); + break; + + case ID_HELP_CONT: + WinHelp(hDlg, HELP_FILE, HELP_CONTENTS, 0L); + break; + + case ID_HELP_INDEX: + WinHelp(hDlg, HELP_FILE, HELP_PARTIALKEY, (DWORD) TEXT("\0")); + break; + + case ID_HELP_USING: + WinHelp(hDlg, HELP_FILE, HELP_HELPONHELP, (DWORD) TEXT("\0")); + break; + + case IDC_ADD: + if (!DialogServerBrowse(hInst, hDlg, &lpSourceServer, &lpDestServer)) { + dwData = (DWORD) ConvertListAdd(lpSourceServer, lpDestServer); + MainListbox_Add(hDlg, dwData, lpSourceServer->Name, lpDestServer->Name); + PostMessage(hDlg, WM_COMMAND, (WPARAM) IDM_ADDSEL, 0); + } + + return TRUE; + + case IDC_DELETE: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + Index = ColumnLB_GetCurSel(hCtrl); + + if (Index != LB_ERR) { + dwData = ColumnLB_GetItemData(hCtrl, Index); + ConvertListDelete((CONVERT_LIST *) dwData); + ColumnLB_DeleteString(hCtrl, Index); + } + + if (!NumServerPairs) { + hCtrl = GetDlgItem(hDlg, IDC_ADD); + SetFocus(hCtrl); + ToggleControls(hDlg, FALSE); + UserOptionsDefaultsReset(); + FileOptionsDefaultsReset(); + + } else { + Index = ColumnLB_GetCurSel(hCtrl); + + if (Index == LB_ERR) + ColumnLB_SetCurSel(hCtrl, 0); + } + + break; + + case IDM_ADDSEL: + ToggleControls(hDlg, TRUE); + break; + + case IDC_LIST1: + if (wmEvent == LBN_SELCHANGE) { + if (NumServerPairs) + ToggleControls(hDlg, TRUE); + } else + if (wmEvent == LBN_DBLCLK) { + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + Index = ColumnLB_GetCurSel(hCtrl); + + if (Index != LB_ERR) { + dwData = ColumnLB_GetItemData(hCtrl, Index); + if (dwData != 0) { + CurrentConvertList = (CONVERT_LIST *) dwData; + + NTServInfoDlg_Do(hDlg); + } + } + } + break; + + case ID_APP_ABOUT: + AboutBox_Do(hDlg); + return TRUE; + + } + + break; + + case WM_MENUSELECT: + // when a menu is selected we must remember which one it was so that + // when F1 is pressed we know what help to bring up. + if (GET_WM_MENUSELECT_HMENU(wParam, lParam)) { + + // Save the menu the user selected + uMenuID = GET_WM_MENUSELECT_CMD(wParam, lParam); + uMenuFlags = GET_WM_MENUSELECT_FLAGS(wParam, lParam); + hMenu = GET_WM_MENUSELECT_HMENU(wParam, lParam); + } + + break; + + default: + if (message == wHelpMessage) { + + if (GET_WM_COMMAND_ID(wParam, lParam) == MSGF_MENU) { + // Get outta menu mode if help for a menu item + if (uMenuID && hMenu) { + // save and restore menu vars so they aren't overwritten by + // the message we are sending + UINT m = uMenuID; + HMENU hM = hMenu; + UINT mf = uMenuFlags; + + SendMessage(hDlg, WM_CANCELMODE, 0, 0L); + + uMenuID = m; + hMenu = hM; + uMenuFlags = mf; + } + + if (!(uMenuFlags & MF_POPUP)) { + switch(uMenuID) { + case ID_FILE_OPEN: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDM_HELP_RCONFIG); + break; + + case ID_FILE_SAVE: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDM_HELP_SCONFIG); + break; + + case ID_FILE_DEFAULT: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDM_HELP_RDCONFIG); + break; + + case IDC_EXIT: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDM_HELP_EXIT); + break; + + } + +#ifdef fooo + // According to winhelp: GetSystemMenu, uMenuID >= 0x7000 + // means system menu items! + // + // This should not be nec since MF_SYSMENU is set! + if (uMenuFlags & MF_SYSMENU || uMenuID >= 0xf000) + dwContext = bMDIFrameSysMenu ? IDH_SYSMENU : IDH_SYSMENUCHILD; + + WFHelp(hwnd); +#endif + } + + } +#ifdef fooo + else if (GET_WM_COMMAND_ID(wParam, lParam) == MSGF_DIALOGBOX) { + + // context range for message boxes + if (dwContext >= IDH_MBFIRST && dwContext <= IDH_MBLAST) + WFHelp(hwnd); + else + // let dialog box deal with it + PostMessage(GetRealParent((HWND)lParam), wHelpMessage, 0, 0L); + } +#endif + + } + + break; + } + + + return (FALSE); // Didn't process the message + +} // DlgMoveIt diff --git a/private/nw/convert/nwconv/nwconv.h b/private/nw/convert/nwconv/nwconv.h new file mode 100644 index 000000000..85a3212d5 --- /dev/null +++ b/private/nw/convert/nwconv/nwconv.h @@ -0,0 +1,25 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HNWCONV_ +#define _HNWCONV_ + +#ifdef __cplusplus +extern "C"{ +#endif + +extern TCHAR NT_PROVIDER[]; +extern TCHAR NW_PROVIDER[]; + +// Common utility routines +void CanonServerName(LPTSTR ServerName); + +extern HINSTANCE hInst; // current instance +extern TCHAR ProgPath[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/nwconv.rc b/private/nw/convert/nwconv/nwconv.rc new file mode 100644 index 000000000..324fed0e0 --- /dev/null +++ b/private/nw/convert/nwconv/nwconv.rc @@ -0,0 +1,954 @@ + +#include +#include "resource.h" +#include "strings.h" +#include "columnlb.h" + +// version info +#include "version.h" + +NWConv ICON moveit.ico +IDR_LISTICONS BITMAP hiericon.bmp +IDR_FILEICONS BITMAP fileicon.bmp +IDR_CHECKICONS BITMAP hierchk.bmp +SizebarHCursor CURSOR sizebarh.cur + +DIALOGMENU MENU PRELOAD DISCARDABLE +{ + POPUP "&File" + { + MENUITEM "&Restore Configuration...\tCtrl+R", ID_FILE_OPEN + MENUITEM "&Save Configuration...\tCtrl+S", ID_FILE_SAVE + MENUITEM "Restore &Default Config...\tCtrl+D", ID_FILE_DEFAULT + MENUITEM SEPARATOR + MENUITEM "E&xit", IDC_EXIT + } + POPUP "&Help" + { + MENUITEM "&Contents", ID_HELP_CONT + MENUITEM "&Search for Help on...", ID_HELP_INDEX + MENUITEM "&How to Use Help", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "&About NWConv...", ID_APP_ABOUT + } +} + +MainAcc ACCELERATORS PRELOAD DISCARDABLE +{ + VK_F1, ID_HELP_CONT, VIRTKEY + "^R", ID_FILE_OPEN + "^S", ID_FILE_SAVE + "^D", ID_FILE_DEFAULT +} + +NWCONV DIALOG DISCARDABLE 15, 40, 331, 148 +STYLE WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP | DS_3DLOOK +CAPTION "Migration Tool for NetWare" +MENU DIALOGMENU +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "&Start Migration",IDOK,262,6,63,14 + PUSHBUTTON "&Trial Migration",IDC_TRIAL,262,23,63,14 + PUSHBUTTON "&Logging...",ID_LOGGING,262,40,63,14 + PUSHBUTTON "E&xit",IDC_EXIT,262,57,63,14 + PUSHBUTTON "Help",IDHELP,262,74,63,14 + GROUPBOX "Servers For Migration",IDC_STATIC,5,3,250,137 + CONTROL "", IDC_LIST1, "ColumnListBox", WS_BORDER | WS_TABSTOP, + 11,14,172,119 + PUSHBUTTON "&Add...",IDC_ADD,190,13,60,14 + PUSHBUTTON "&Delete",IDC_DELETE,190,30,60,14 + PUSHBUTTON "&User Options...",IDC_USERINF,190,47,60,14 + PUSHBUTTON "File &Options...",IDC_FILEINF,190,64,60,14 +} + +DlgGetServ DIALOG DISCARDABLE 0, 0, 293, 64 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Select Servers For Migration" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,242,6,45,14,WS_DISABLED + PUSHBUTTON "Cancel",IDCANCEL,242,23,45,14 + PUSHBUTTON "&Help",IDHELP,242,40,45,14 + LTEXT "&From NetWare Server:",IDC_STATIC,9,17,79,8 + EDITTEXT IDC_EDITNWSERV,89,15,73,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_NWBROWSE,166,15,21,12 + LTEXT "&To Windows NT Server:",IDC_STATIC,9,36,79,8 + EDITTEXT IDC_EDITNTSERV,89,34,73,13,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_NTBROWSE,166,34,21,13 +} + + + +DLGNEWUSERS DIALOG DISCARDABLE 0, 0, 276, 163 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "User and Group Options" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,220,6,50,14 + PUSHBUTTON "Cancel",IDCANCEL,220,23,50,14 + PUSHBUTTON "&Help",IDHELP,220,40,50,14 + PUSHBUTTON "&Advanced >>",IDC_ADVANCED,220,116,50,14 + + CONTROL "&Transfer Users and Groups", IDC_CHKUSERS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,5,100,8 + + CONTROL "Use &Mappings in File:", IDC_CHKMAPPING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,17,90,8 + EDITTEXT IDC_MAPPINGFILE,105,15,57,12,ES_AUTOHSCROLL + PUSHBUTTON "Create",IDC_BTNMAPPINGFILE,167,10,30,12 + PUSHBUTTON "Edit",IDC_BTNMAPPINGEDIT,167,24,30,12 + + CONTROL "", IDC_TABUSERS, "BOOKTAB", WS_CLIPSIBLINGS | + WS_CLIPCHILDREN | WS_TABSTOP, 5, 40, 205, 95 + + CONTROL "No Password",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | + WS_GROUP | WS_TABSTOP,17,70,75,8 + CONTROL "Password is Username",IDC_RADIO2,"Button", + BS_AUTORADIOBUTTON,17,85,85,8 + CONTROL "Password is:",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON, + 17,100,57,8 + EDITTEXT IDC_PWCONST,75,100,57,12,ES_AUTOHSCROLL + CONTROL "User Must Change Password",IDC_CHKPWFORCE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,120,126,8 + + LTEXT "Duplicate Names:",IDC_STATDUP,12,60,70,8, NOT WS_VISIBLE + CONTROL "Log Error",IDC_RADIO4,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_GROUP | WS_TABSTOP, + 17,70,105,8 + CONTROL "Ignore",IDC_RADIO5,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE,17,85,100,8 + CONTROL "Overwrite with new Info",IDC_RADIO6,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE,17,100,100,8 + CONTROL "Add prefix:",IDC_RADIO7,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE,17,115,45,8 + EDITTEXT IDC_USERCONST,75,115,57,12,ES_AUTOHSCROLL | NOT WS_VISIBLE + + + CONTROL "Log Error",IDC_RADIO8,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_GROUP | WS_TABSTOP, + 17,70,105,8 + CONTROL "Ignore",IDC_RADIO9,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE,17,85,100,8 + CONTROL "Add prefix:",IDC_RADIO10,"Button", + BS_AUTORADIOBUTTON | NOT WS_VISIBLE,17,100,45,8 + EDITTEXT IDC_GROUPCONST,75,100,57,12,ES_AUTOHSCROLL | NOT WS_VISIBLE + + + CONTROL "Use Supervisor Defaults", IDC_CHKSUPER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP | NOT WS_VISIBLE, + 17,70,100,8 + CONTROL "Add Supervisors to the Administrators Group", IDC_CHKADMIN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP | NOT WS_VISIBLE, + 17,85,180,8 + CONTROL "Migrate NetWare Specific Account Information", IDC_CHKFPNW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP | NOT WS_VISIBLE, + 17,100,180,8 + + CONTROL "", IDC_DEFAULTBOX, "static", SS_BLACKRECT | WS_CHILD, + 272, 144, 4, 4 + + CONTROL "Transfer Users to Trusted &Domain:", IDC_CHKTRUSTED,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP, + 5,151,132,8 + COMBOBOX IDC_TRUSTED,140,149,85,60,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + +} + + +MAPCREATE DIALOG DISCARDABLE 0, 0, 250, 140 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Create Mapping File" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,195,6,50,14 + PUSHBUTTON "Cancel",IDCANCEL,195,23,50,14 + + LTEXT "Use &Mappings in File:",IDC_STATIC,5,17,90,8 + EDITTEXT IDC_MAPPINGFILE,105,15,57,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BTNMAPPINGFILE,167,15,21,12 + + + GROUPBOX " ",IDC_STATIC,5,35,183,85 + CONTROL "Include User Names", IDC_USERS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,9,35,100,8 + + LTEXT "Default Password:",IDC_STATIC,10,50,70,8 + CONTROL "No Password",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | + WS_GROUP | WS_TABSTOP,15,65,75,8 + CONTROL "Password is Username",IDC_RADIO2,"Button", + BS_AUTORADIOBUTTON,15,80,85,8 + CONTROL "Password is:",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON, + 15,95,57,8 + EDITTEXT IDC_PWCONST,85,95,57,12,ES_AUTOHSCROLL + + CONTROL "Include Group Names", IDC_GROUPS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,125,100,8 + +} + + +DLGSERVSEL DIALOG DISCARDABLE 0, 0, 231, 190 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Select Windows NT Server" +FONT 8, "MS Shell Dlg" +{ + PUSHBUTTON "OK",IDC_ALTOK,175,6,50,14 + PUSHBUTTON "Cancel",IDCANCEL,175,23,50,14 + PUSHBUTTON "&Help",IDHELP,175,40,50,14 + LTEXT "&Server:",IDC_STATIC,5,25,30,8 + EDITTEXT IDC_EDIT1,35,23,78,12,ES_AUTOHSCROLL + LTEXT "Select Server",IDC_STATIC,2,48,90,8 + LISTBOX IDC_LIST1,2,58,226,130, LBS_OWNERDRAWFIXED | + LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY +} + + +DLGLOGGING DIALOG DISCARDABLE 0, 0, 185, 88 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Logging" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,119,6,60,14 + PUSHBUTTON "Cancel",IDCANCEL,119,23,60,14 + PUSHBUTTON "&Help",IDHELP,119,40,60,14 + + CONTROL "Popup on errors",IDC_CHKERROR,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,5,20,76,8 + CONTROL "Verbose User/Group Logging",IDC_CHKUVERBOSE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,5,35,110,8 + CONTROL "Verbose File Logging",IDC_CHKFVERBOSE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,5,50,110,8 + + PUSHBUTTON "View Log Files...",IDC_VIEWLOG,119,71,60,14 +} + + +STATUSDLG DIALOG DISCARDABLE 0, 0, 270, 127 +STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_3DLOOK +CAPTION "Converting..." +FONT 8, "MS Shell Dlg" +{ + LTEXT "Processing Migration:",IDC_STATIC,5,10,80,10 + LTEXT "0",IDC_S_CUR_CONV,90,10,25,8 + LTEXT "of:",IDC_STATIC,125,10,15,10 + LTEXT "0",IDC_S_TOT_CONV,145,10,25,7 + LTEXT "From:",IDC_STATIC,5,25,25,8 + LTEXT "To:",IDC_STATIC,5,35,25,8 + LTEXT "",IDC_S_SRCSERV,35,25,84,8 + LTEXT "",IDC_S_DESTSERV,35,35,85,8 + + GROUPBOX "Totals",IDC_STATIC,130,25,135,68 + LTEXT "Migrations Completed:",IDC_STATIC,137,37,83,8 + LTEXT "Groups Transferred:",IDC_STATIC,137,47,68,8 + LTEXT "Users Transferred:",IDC_STATIC,137,57,68,8 + LTEXT "Files Transferred:",IDC_STATIC,137,67,68,8 + LTEXT "Errors:",IDC_STATIC,137,77,75,7 + RTEXT "0",IDC_S_TOT_COMP,225,37,35,8 + RTEXT "0",IDC_S_TOT_GROUPS,225,47,35,8 + RTEXT "0",IDC_S_TOT_USERS,225,57,35,8 + RTEXT "0",IDC_S_TOT_FILES,225,67,35,8 + RTEXT "0",IDC_S_TOT_ERRORS,225,77,35,8 + + LTEXT "",IDC_S_CONVTXT,5,55,70,8 + RTEXT "0",IDC_S_CUR_NUM,25,65,35,8 + LTEXT "of:",IDC_STATIC,64,65,10,8 + RTEXT "0",IDC_S_CUR_TOT,77,65,51,8 + + LTEXT "",IDC_PANEL1,5,75,30,8 + RTEXT "",IDC_PANEL2,8,85,52,8 + LTEXT "",IDC_PANEL4,64,85,10,8 + RTEXT "",IDC_PANEL3,77,85,51,8 + + GROUPBOX "",IDC_S_ITEMLABEL,5,95,260,25 + + LTEXT "",IDC_S_STATUSITEM,9,107,245,8 +} + + +CONVERSIONEND DIALOG DISCARDABLE 0, 0, 200, 75 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Transfer Completed" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,135,6,60,14 + PUSHBUTTON "View Log Files...",IDC_VIEWLOG,135,23,60,14 + + GROUPBOX "Totals",IDC_STATIC,5,5,125,65 + LTEXT "Migrations Completed:",IDC_STATIC,10,15,83,8 + LTEXT "Groups Transferred:",IDC_STATIC,10,25,68,8 + LTEXT "Users Transferred:",IDC_STATIC,10,35,68,8 + LTEXT "Files Transferred:",IDC_STATIC,10,45,68,8 + LTEXT "Errors:",IDC_STATIC,10,55,68,8 + RTEXT "0",IDC_S_TOT_COMP,95,15,30,8 + RTEXT "0",IDC_S_TOT_GROUPS,95,25,30,8 + RTEXT "0",IDC_S_TOT_USERS,95,35,30,8 + RTEXT "0",IDC_S_TOT_FILES,95,45,30,8 + RTEXT "0",IDC_S_TOT_ERRORS,95,55,30,8 + +} + + +FILEMAIN DIALOG DISCARDABLE 0, 0, 308, 135 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "File Options" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,251,6,50,14 + PUSHBUTTON "Cancel",IDCANCEL,251,23,50,14 + PUSHBUTTON "&Help",IDHELP,251,40,50,14 + + GROUPBOX " ",IDC_STATIC,5,5,241,128 + CONTROL "Transfer Files", IDC_CHKFILES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,9,5,100,8 + + CONTROL "", IDC_LIST1, "ColumnListBox", WS_BORDER | WS_TABSTOP, + 11,17,172,107 + + PUSHBUTTON "&Add...",IDC_ADD,188,25,50,14 + PUSHBUTTON "&Delete",IDC_DELETE,188,42,50,14 + PUSHBUTTON "&Modify...",IDC_MODIFY,188,59,50,14 + PUSHBUTTON "&Files...",IDC_FILES,188,76,50,14 +} + + +FSELECTMENU MENU PRELOAD DISCARDABLE +{ + POPUP "&Tree" + { + MENUITEM "E&xpand One Level", IDM_EXP_ONE + MENUITEM "Expand &Branch", IDM_EXP_BRANCH + MENUITEM "Expand &All", IDM_EXP_ALL + MENUITEM "&Collapse Branch", IDM_COLLAPSE + } + POPUP "T&ransfer" + { + MENUITEM "&Hidden Files", IDM_HIDDEN + MENUITEM "&System Files", IDM_SYSTEM + } +} + + +FILESELECT DIALOG DISCARDABLE 0, 0, 308, 135 +STYLE WS_THICKFRAME | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Files To Transfer" +MENU FSELECTMENU +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,77,106,45,14 + PUSHBUTTON "Cancel",IDCANCEL,132,106,45,14 + PUSHBUTTON "&Help",IDHELP,187,106,45,14 + + LISTBOX IDC_LIST1,10,10,142,101, LBS_OWNERDRAWFIXED | LBS_WANTKEYBOARDINPUT | + WS_VSCROLL | WS_TABSTOP + + LISTBOX IDC_LIST2,155,10,142,101, LBS_OWNERDRAWFIXED | + LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP +} + + +NWShareSelect DIALOG DISCARDABLE 0, 0, 310, 103 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Add Volume to Copy" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK, 263,6,45,14 + PUSHBUTTON "Cancel",IDCANCEL,263,23,45,14 + PUSHBUTTON "&Help",IDHELP,263,40,45,14 + + GROUPBOX "",IDC_FSERVER,5,5,250,30 + LTEXT "Volume:",IDC_STATIC,10,18,30,8 + LTEXT "",IDC_VOLUME,60,18,105,8, NOT WS_VISIBLE + COMBOBOX IDC_COMBO1,60,16,85,60,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + + GROUPBOX "",IDC_TSERVER,5,44,250,51 + LTEXT "Share:",IDC_STATIC,10,57,25,8 + COMBOBOX IDC_COMBO2,60,55,85,60,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + + PUSHBUTTON "New Share...",IDC_NEWSHARE,200,55,50,14 + PUSHBUTTON "Properties...",IDC_PROPERTIES,200,72,50,14 + + LTEXT "Subdirectory:",IDC_STATIC,10,78,45,8 + EDITTEXT IDC_EDIT1,60,75,135,12,ES_AUTOHSCROLL +} + + +NWShareAdd DIALOG DISCARDABLE 0, 0, 280, 60 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "New Share" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK, 230,6,45,14 + PUSHBUTTON "Cancel",IDCANCEL,230,23,45,14 + PUSHBUTTON "&Help",IDHELP,230,40,45,14 + + LTEXT "&Share Name:",IDC_STATIC,10,10,45,8 + LTEXT "",IDC_SHARENAME,60,10,100,8 + EDITTEXT IDC_EDIT1,60,7,100,12,ES_AUTOHSCROLL + + LTEXT "&Path:",IDC_STATIC,10,30,45,8 + EDITTEXT IDC_EDIT2,60,27,160,12,ES_AUTOHSCROLL + +} + + +PasswordEnter DIALOG DISCARDABLE 52, 26, 225, 70 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK +CAPTION "Enter Network Credentials" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK", IDOK, 175,6,45,14 + PUSHBUTTON "Cancel", IDCANCEL, 175,23,45,14 + + LTEXT "Incorrect user credentials for:", IDC_STATIC, 7, 7, 99, 8 + LTEXT "", IDC_SERVNAME, 12, 17, 99, 8 + LTEXT "&Connect As:", IDC_STATIC, 7, 32, 56, 8 + EDITTEXT IDC_USERNAME, 55, 30, 103, 12 + LTEXT "&Password:", IDC_STATIC, 7, 52, 56, 8 + EDITTEXT IDC_PASSWORD, 55, 50, 103, 12, ES_PASSWORD +} + + +PanelDLG DIALOG DISCARDABLE 0, 0, 200, 84 +STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_3DLOOK +CAPTION "" +FONT 8, "MS Shell Dlg" +{ + LTEXT "",IDC_PANEL1,5,10,195,8 + LTEXT "",IDC_PANEL2,5,20,45,8 + LTEXT "",IDC_PANEL3,5,30,45,8 + LTEXT "",IDC_PANEL4,5,40,45,8 + LTEXT "",IDC_PANEL5,5,50,45,8 + + LTEXT "",IDC_PANEL6,52,10,140,8 + LTEXT "",IDC_PANEL7,52,20,140,8 + LTEXT "",IDC_PANEL8,52,30,140,8 + LTEXT "",IDC_PANEL9,52,40,140,8 + LTEXT "",IDC_PANEL10,52,50,140,8 + + PUSHBUTTON "Cancel", IDCANCEL, 77,65,45,14 +} + + +ALERTSEL DIALOG DISCARDABLE 0, 0, 183, 135 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_3DLOOK +CAPTION "Warning" +FONT 8, "MS Shell Dlg" +{ + CTEXT "",IDC_PANEL1,5,10,173,40 + + LISTBOX IDC_LIST1,5,55,173,40, WS_VSCROLL | WS_TABSTOP + + CTEXT "Do you want to continue with the conversion?", + IDC_STATIC,5,100,173,8 + + PUSHBUTTON "&Yes", IDYES, 44, 113, 45, 14 + PUSHBUTTON "&No", IDNO, 94, 113, 45, 14 + +} + + +NTSERVINFO DIALOG DISCARDABLE 0, 0, 183, 185 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_3DLOOK +CAPTION "Server Info" +FONT 8, "MS Shell Dlg" +{ + LTEXT "&Server:",IDC_STATIC,5,10,50,8 + COMBOBOX IDC_COMBO1,55,7,100,40,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Type:",IDC_STATIC,5,22,50,8 + LTEXT "",IDC_TYPE,55,22,130,8 + + LTEXT "Version:",IDC_STATIC,5,32,50,8 + LTEXT "",IDC_VERSION,55,32,130,8 + + LTEXT "&Drives:",IDC_T_DRIVES,5,45,50,8, NOT WS_VISIBLE + LISTBOX IDC_LIST1,5,55,173,40, WS_VSCROLL | WS_TABSTOP | NOT WS_VISIBLE + + LTEXT "S&hares:",IDC_T_SHARES,5,105,50,8, NOT WS_VISIBLE + LISTBOX IDC_LIST2,5,115,173,40, WS_VSCROLL | WS_TABSTOP | NOT WS_VISIBLE + + LTEXT "&Volumes:",IDC_T_VOLUMES,5,45,50,8 + LISTBOX IDC_LIST3,5,55,173,100, WS_VSCROLL | WS_TABSTOP + + DEFPUSHBUTTON "OK",IDOK,71,165,40,14 + +} + + +NAMEERROR DIALOG DISCARDABLE 0, 0, 183, 90 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_3DLOOK +CAPTION "" +FONT 8, "MS Shell Dlg" +{ + CTEXT "",IDC_PANEL1, 5,10,173,20 + + LTEXT "Name:", IDC_STATIC, 5, 40, 50, 8 + LTEXT "", IDC_OLDNAME, 60, 40, 115, 8 + + LTEXT "New Name:", IDC_STATIC, 5, 55, 50, 8 + EDITTEXT IDC_NEWNAME, 60,52,115,12,ES_AUTOHSCROLL + + DEFPUSHBUTTON "&OK", IDRETRY, 19, 70, 45, 14 + PUSHBUTTON "&Cancel", IDIGNORE, 69, 70, 45, 14 + PUSHBUTTON "&Abort", IDABORT, 119, 70, 45, 14 + +} + + + +STRINGTABLE DISCARDABLE +{ + IDS_APPNAME "NWConv" + + IDS_DISK_SPACE_UNAVAIL "Unavailable" + IDS_DISK_SPACE "%13s KB Free" + IDS_MATH_COPR_NOTPRESENT "Not present" + IDS_MATH_COPR_PRESENT "Present" + IDS_PHYSICAL_MEM "%13s KB Free" + + IDS_USERFILTERSTRING "Mapping Files(*.MAP)|*.map|" + IDS_MAINFILTERSTRING "Configuration Files(*.CNF)|*.cnf|" + + IDS_TXTWARNING "Warning" + IDS_RESTOREDEFAULTS "This will delete all servers from\nthe list of servers to convert\nand all the configuration information." + + IDS_MAPNEWNAME "NewName" + IDS_MAPNEWPASSWORD "Password" + IDS_MAPGROUPS "__GROUPS__" + + IDS_NOREADMAP "Can't access the specified mapping file" + IDS_MAPCREATED "Mapping file created succesfully.\nDo you want to edit it?" + IDS_MAPCREATEFAIL "Mapping file could not be created" + IDS_NOEDITMAP "Can't access the specified mapping file, do you want to browse for it?" + + IDS_CRLF "\r\n" + + IDS_SUN "Sun" + IDS_MON "Mon" + IDS_TUE "Tue" + IDS_WED "Wed" + IDS_THU "Thu" + IDS_FRI "Fri" + IDS_SAT "Sat" + + IDS_SUNDAY "Sunday" + IDS_MONDAY "Monday" + IDS_TUESDAY "Tuesday" + IDS_WEDNESDAY "Wednesday" + IDS_THURSDAY "Thursday" + IDS_FRIDAY "Friday" + IDS_SATURDAY "Saturday" + + IDS_NWCANT_CON "Cannot connect to server: %s" + IDS_NWNO_ADMIN "You do not have administrator or supervisor privileges on %s" + + IDS_LINE ";+----------------------------------------------------------------------------+\r\n" + IDS_BRACE ";| %-74s |\r\n" + IDS_YES "Yes" + IDS_NO "No" + + IDS_E_NWLOG "Error: Can't write LogFile" + + IDS_LOCKED_OUT "Locked out" + + IDS_D_1 "Volume:" + IDS_D_2 "Dir:" + IDS_D_3 "File:" + IDS_D_4 "Total Bytes:" + IDS_D_5 "Share Properties" + IDS_D_6 "Modify Destination" + IDS_D_7 "From Server: " + IDS_D_8 "To Server: " + IDS_D_9 "Source Files" + IDS_D_10 "Destination" + + IDS_D_11 "NetWare Server" + IDS_D_12 "Windows NT Server" + + IDS_D_13 " Free: %-14s Allocated: %-14s" + IDS_D_14 " (Drive Invalid)" + + IDS_D_15 "The following file conversions point to drives that are not NTFS.\n\nFile permissions will only be transfered if the destination drive is an NTFS Drive." + IDS_D_16 "There does not appear to be enough space on the destination drives for the following file transfers to take place." + + IDS_D_17 "Transfer Aborted" + + IDS_D_18 "Converting User:" + IDS_D_19 "User:" + + IDS_D_20 "Converting Group:" + IDS_D_21 "Group:" + + IDS_D_22 "Verifying Information" + + IDS_S_1 "Administrators" + IDS_S_2 "SYSTEM" + IDS_S_3 "MAIL" + IDS_S_4 "LOGIN" + IDS_S_5 "ETC" + IDS_S_6 "SYS" + + IDS_S_7 "Out of Memory" + IDS_S_8 "NwConv - Error" + + IDS_S_9 "NTFS" + IDS_S_10 "\\\\%s\\ADMIN$" + IDS_S_11 "ADMIN$" + + IDS_S_12 "System\\CurrentControlSet\\Control\\ProductOptions" + IDS_S_13 "ProductType" + IDS_S_14 "LanmanNT" + + IDS_S_15 "Windows NT(R) Server" + IDS_S_16 "NetWare(R) Server" + IDS_S_17 " Free Space: %13s" + IDS_S_18 " Path: %s" + IDS_S_19 " Size: %13s" + + IDS_S_20 "CNF" + + IDS_S_21 "Name" + IDS_S_22 "DisplayName" + IDS_S_23 "System\\CurrentControlSet\\Services\\NWCWorkstation\\networkProvider" + IDS_S_24 "System\\CurrentControlSet\\Services\\NWCWorkstation" + IDS_S_25 "System\\CurrentControlSet\\Services\\LanmanWorkstation\\networkProvider" + IDS_S_26 "NWCWorkstation" + + IDS_S_27 "\\\\%s\\SYS" + + IDS_S_28 "SUPERVISOR" + IDS_S_29 "GUEST" + IDS_S_30 "ADMIN" + IDS_S_31 "EVERYONE" + IDS_S_32 "Domain Admins" + IDS_S_33 "Domain Users" + + IDS_S_34 "[SRWCEMFA]" + + IDS_S_35 "Select NetWare Server" + + IDS_S_36 ".MAP" + IDS_S_37 "MAP" + + IDS_S_38 "Passwords" + IDS_S_39 "Usernames" + IDS_S_40 "Group Names" + IDS_S_41 "Defaults" + + IDS_S_42 "Domain Admins" + IDS_S_43 "Print Operators" + + IDS_S_44 "Enumerating Users:" + IDS_S_45 "Enumerating Groups:" + IDS_S_46 "Adding Users to Group: %s" + IDS_S_47 "Adding Security Equivalences for User: %s" + IDS_S_48 "Adding Print Operators: %s" + + IDS_S_49 "CDFS" + + + IDS_E_1 "NWConv - CRITICAL ERROR" + IDS_E_2 "Error" + IDS_E_3 "Path must be in the form of: drive:\\path" + IDS_E_4 "The share already exists" + IDS_E_5 "Cannot connect to server: %s" + IDS_E_6 "No Admin Priviledge on: %s" + IDS_E_7 "Could not get Server Information for: %s" + IDS_E_8 "%s is not a Windows NT Server" + IDS_E_9 "Cannot connect to server: %s\n\n%s" + + IDS_E_10 "Configuration File Corrupt" + IDS_E_11 "The configuration file was created with a different version of the program" + + IDS_E_12 "Client Services for NetWare not installed" + + IDS_E_13 "Error Creating Log File: %s" + + IDS_E_14 "Already Converting %s" + + IDS_E_15 "This will end the conversion. Are you sure you want to do this?" + IDS_E_16 "Warning" + + IDS_E_17 "The specified mapping file already exists, do you want to overwrite it?" + + IDS_E_18 "%s is not a NetWare Server" + + IDS_M_1 "NWConv Mapping for: %s" + IDS_M_2 "Version: 1.1" + IDS_M_3 "Format Is:" + IDS_M_4 " OldName, NewName, Password" + IDS_M_5 "[USERS]\r\n" + IDS_M_6 "\r\n[GROUPS]\r\n" + + IDS_M_7 "USERS" + IDS_M_8 "GROUPS" + + IDS_L_1 " Midnight AM Noon PM\r\n" + IDS_L_2 " 12 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11\r\n" + IDS_L_3 " +-----------------------------------------------------------------------+\r\n" + + IDS_L_4 "Error: Writing File" + IDS_L_5 "Error: Writing File - out-of-space" + IDS_L_6 "Error: Can't create thread to copy file" + + IDS_L_7 "[New Shares]\r\n" + IDS_L_8 "Path: %s \r\n" + IDS_L_9 "Access Rights for: %s" + IDS_L_10 "[Access Rights]\r\n" + + IDS_L_11 "Unable to open source" + IDS_L_12 "Unable to open source, error code %d" + IDS_L_13 "Unable to get time of source" + IDS_L_14 "Unable to create destination, error code %d" + IDS_L_15 "Unable to set time of destination" + IDS_L_16 "Unable to set attributes of destination" + + IDS_L_17 "Source Directory: %s\r\n" + IDS_L_18 "Dest Directory : %s\r\n" + IDS_L_19 "File: %s" + IDS_L_20 "[Files]\r\n" + + IDS_L_21 "[RAHS]" + IDS_L_22 "Error Copying File: %s -> %s\r\n" + + IDS_L_23 "Files are shown in the following format:" + IDS_L_24 " [Files]" + IDS_L_25 " 1,234,567 [RAHS] TEST.TXT" + IDS_L_26 " | |||| |" + IDS_L_27 " | |||| +- Name of the File" + IDS_L_28 " | ||||" + IDS_L_29 " | |||+---- System" + IDS_L_30 " | ||+----- Hidden" + IDS_L_31 " | |+------ Archived" + IDS_L_32 " | +------- Read Only" + IDS_L_33 " |" + IDS_L_34 " +---------- File size (in Bytes)" + IDS_L_35 "" + IDS_L_36 "The Access Rights are shown in the following format:" + IDS_L_37 " [Access Rights]" + IDS_L_38 " [SRWCEMFA] TestUser" + IDS_L_39 " |||||||| |" + IDS_L_40 " |||||||| +- User or Group the Rights apply to" + IDS_L_41 " ||||||||" + IDS_L_42 " |||||||+---- Access Control" + IDS_L_43 " ||||||+----- File Scan" + IDS_L_44 " |||||+------ Modify" + IDS_L_45 " ||||+------- Erase" + IDS_L_46 " |||+-------- Create" + IDS_L_47 " ||+--------- Write" + IDS_L_48 " |+---------- Read" + IDS_L_49 " +----------- Supervisory" + + IDS_L_50 "Converting Files:" + IDS_L_51 "File:" + + IDS_L_52 "Copying Files From Volume: %s\r\n" + IDS_L_53 "To Share: %s\r\n" + IDS_L_54 "Total Files Converted: %s\r\n" + IDS_L_55 "Bytes Transferred: %s\r\n" + + IDS_L_56 "Logon Hours:\r\n" + IDS_L_57 "New Account Info:\r\n" + IDS_L_58 "Name: %s\r\n" + IDS_L_59 "Password: %s\r\n" + IDS_L_60 "Guest" + IDS_L_61 "User" + IDS_L_62 "Admin" + IDS_L_63 "Privilege: %s\r\n" + IDS_L_64 "Home Dir: %s\r\n" + IDS_L_65 "Comment: %s\r\n" + IDS_L_66 "Flags:\r\n" + IDS_L_67 "Execute login script: %s\r\n" + IDS_L_68 "Account disabled: %s\r\n" + IDS_L_69 "Deleting prohibited: %s\r\n" + IDS_L_70 "Home dir required: %s\r\n" + IDS_L_71 "Password required: %s\r\n" + IDS_L_72 "User can change password: %s\r\n" + IDS_L_73 "Script path: %s\r\n" + IDS_L_74 "Full Name: %s\r\n" + IDS_L_75 "Logon Server: %s\r\n" + + IDS_L_76 "Error %d: Adding Access Rights\r\n" + IDS_L_77 "Error %d: Adding Access Rights. User/Group: %s\r\n" + + IDS_L_78 "No Access (None)" + IDS_L_79 "Full Control (All)" + IDS_L_80 "R" + IDS_L_81 "W" + IDS_L_82 "X" + IDS_L_83 "D" + IDS_L_84 "P" + IDS_L_85 "(RX)" + IDS_L_86 "Read (RX)" + IDS_L_87 "(WX)" + IDS_L_88 "Add (WX)" + IDS_L_89 "(RWX)" + IDS_L_90 "Add & Read (RWX)" + IDS_L_91 "(RWXD)" + IDS_L_92 "Change (RWXD)" + IDS_L_93 "Special Access %s" + + IDS_L_94 "Minimum Password Length: %li\r\n" + IDS_L_95 "Maximum Password Age: %li days\r\n" + IDS_L_96 "Force Logoff: %li\r\n" + + IDS_L_97 ";| Created: %-65s |\r\n" + IDS_L_98 ";| System : %-65s |\r\n" + IDS_L_99 ";| Admin : %-65s |\r\n" + IDS_L_100 ";| Version: %1d.%-63d |\r\n" + + IDS_L_101 "Migration Tool for NetWare Error Log File" + IDS_L_102 "Migration Tool for NetWare Log File" + IDS_L_103 "Migration Tool for NetWare Summary Log File" + + IDS_L_104 "Login Times:\r\n" + + IDS_L_105 "Original Account Info:\r\n" + IDS_L_106 "Name: " + IDS_L_107 "(Never)" + IDS_L_108 "(Unlimited)" + IDS_L_109 "Account expires: " + IDS_L_110 "Restrictions:\r\n" + IDS_L_111 "Only SUPERVISOR can change password\r\n" + IDS_L_112 "Anyone who knows password can change it\r\n" + IDS_L_113 "Unique passwords required: %s\r\n" + IDS_L_114 "# days to Password Expiration: " + IDS_L_115 "Initial Grace Logins: " + IDS_L_116 "Minimum Password Length: %u\r\n" + IDS_L_117 "Maximum Number of Connections: " + IDS_L_118 "Default Current Account Balance: %lu\r\n" + IDS_L_119 "Default Credit Limit: %lu\r\n" + IDS_L_120 "Max Disk Blocks: " + IDS_L_121 "Account disabled: %s\r\n" + IDS_L_122 "Password expires: " + IDS_L_123 "Grace Logins: " + IDS_L_124 "Number of login failures: %u\r\n" + + IDS_L_125 "[Shares]\r\n" + + IDS_L_126 "Number of Migrations = %i\r\n" + IDS_L_127 "[Servers]\r\n" + IDS_L_128 "From: %-15s To: %s\r\n" + IDS_L_129 "Server Information" + IDS_L_130 "Windows NT(R) Server\r\n" + IDS_L_131 "Version: %lu.%lu\r\n" + IDS_L_132 "[Drives]\r\n" + IDS_L_133 "Free Space: %s\r\n" + IDS_L_134 "NetWare(R) Server\r\n" + IDS_L_135 "Version: %u.%u\r\n" + + IDS_L_136 "[Transfer Options]\r\n" + IDS_L_137 "Convert Users and Groups: %s\r\n" + IDS_L_138 "Use mapping file: %s\r\n" + IDS_L_139 "Mapping File: %s\r\n" + IDS_L_140 "User Transfer Options:\r\n" + IDS_L_141 "Passwords: " + IDS_L_142 "1 - Use NULL\r\n" + IDS_L_143 "2 - Password is username\r\n" + IDS_L_144 "3 - Use constant: %s\r\n" + IDS_L_145 "User must change password: %s\r\n" + IDS_L_146 "Duplicate Names: " + IDS_L_147 "Duplicate Groups: " + IDS_L_148 "Log Error\r\n" + IDS_L_149 "Ignore\r\n" + IDS_L_150 "Pre-pend constant: %s\r\n" + IDS_L_151 "Overwrite with new Info\r\n" + IDS_L_152 "Use supervisor defaults: %s\r\n" + IDS_L_153 "Add Supervisors to the Administrators Group: %s\r\n" + IDS_L_154 "Transfer users to trusted domain: %s\r\n" + + IDS_L_155 "[File Options]\r\n" + IDS_L_156 "Convert Files: %s\r\n" + + IDS_L_157 "From: %-15s" + IDS_L_158 "To: %-15s") + IDS_L_159 "Converted: %-40s" + + IDS_L_160 "Users to Transfer\r\n" + IDS_L_161 "+--------------------------------------------------+\r\n" + + IDS_L_162 "(Error: Name too Long)" + IDS_L_163 "(Duplicate)" + IDS_L_164 "(Error: Name Invalid)" + + IDS_L_165 "User Name too long" + IDS_L_166 "Duplicate User Name" + IDS_L_167 "User Name Contains Invalid Characters" + IDS_L_168 "Error Transfering User Name" + + IDS_L_169 "[Users]\r\n" + IDS_L_170 "Number of Users = %i\r\n\r\n" + IDS_L_171 "[Transferring Users]\r\n" + + IDS_L_172 "(Duplicate)\r\n\r\n" + IDS_L_173 "Error: Duplicate User Name\r\n" + IDS_L_174 "(Error: Name too Long)\r\n\r\n" + IDS_L_175 "Error: User Name too long\r\n" + IDS_L_176 "(Error: Name Invalid)\r\n\r\n" + IDS_L_177 "Error: User Name Invalid\r\n" + + IDS_L_178 "(Error: Saving User)\r\n" + IDS_L_179 "Error: Saving User Name\r\n" + + IDS_L_180 "(Added)" + + IDS_L_181 "Total Users Converted: %s\r\n" + + IDS_L_182 "Group Name too long" + IDS_L_183 "Duplicate Group Name" + IDS_L_184 "Group Name Contains Invalid Characters" + IDS_L_185 "Error Transfering Group Name" + + IDS_L_186 "[Transferring Groups]\r\n" + IDS_L_187 "[Groups]\r\n" + IDS_L_188 "Number Groups = %li\r\n" + + IDS_L_189 "Error: Duplicate Group Name\r\n" + IDS_L_190 "Error: Group Name too long\r\n" + IDS_L_191 "Error: Group Name Invalid\r\n" + IDS_L_192 "(Error: Saving Group)" + IDS_L_193 "Error: Saving Group Name\r\n" + + IDS_L_194 "[Adding Users to Groups]\r\n" + IDS_L_195 "Error: Adding user [%s] to Group: %s\r\n" + IDS_L_196 "(Error: Adding User)" + IDS_L_197 "Could not enumerate users for Group: %s\r\n" + + IDS_L_198 "[Converting Security Equivalences]\r\n" + IDS_L_199 "[Security Equivalences]\r\n" + + IDS_L_200 "[Converting Print Operators]\r\n" + IDS_L_201 "[Print Operators]\r\n" + + IDS_L_202 "Total Groups Converted: %s\r\n" + + IDS_L_203 "Setting User Defaults from Supervisor Defaults" + IDS_L_204 "[New Defaults: %s]\r\n" + IDS_L_205 "[Original Defaults: %s]\r\n" + IDS_L_206 "[Supervisor Defaults: %s]\r\n" + + IDS_L_207 "Conversion = Trial\r\n" + IDS_L_208 "Conversion = Regular\r\n" + + IDS_L_209 "Error: Accessing Server: %s\r\n" + IDS_L_210 "Error: Getting Users on Server: %s\r\n" + IDS_L_211 "Error: Getting Groups on Server: %s\r\n" + + IDS_L_212 "[Transferring Files]\r\n" + + IDS_L_213 "Bytes:" + IDS_L_214 "of:" + + IDS_L_215 "Conversion Aborted: %s\r\n" + IDS_L_216 "Conversion Finished: %s\r\n" + + IDS_L_217 "Error: Accessing Mapping File: %s\r\n" + + IDS_L_218 "Error: Getting Users from Mapping File: %s\r\n" + IDS_L_219 "Error: Getting Groups from Mapping File: %s\r\n" + +} diff --git a/private/nw/convert/nwconv/nwlog.c b/private/nw/convert/nwconv/nwlog.c new file mode 100644 index 000000000..fd88a56b0 --- /dev/null +++ b/private/nw/convert/nwconv/nwlog.c @@ -0,0 +1,746 @@ +/* + +-------------------------------------------------------------------------+ + | Logging Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [NWLog.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Dec 01, 1993] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Jun 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" + +#include +#include +#include + +#define VER_HI 1 +#define VER_LOW 1 + +HANDLE hErr = NULL; +HANDLE hLog = NULL; +HANDLE hSummary = NULL; + +#define STD_EXT "LOG" +#define ERR_FILENAME "Error." +#define LOG_FILENAME "LogFile." +#define SUMMARY_FILENAME "Summary." + +#define MAX_LOG_STR 1024 +#define FILENAME_LOG "LogFile.LOG" +#define FILENAME_ERROR "Error.LOG" +#define FILENAME_SUMMARY "Summary.LOG" + +static char LogFileName[MAX_PATH + 1]; +static char ErrorLogFileName[MAX_PATH + 1]; +static char SummaryLogFileName[MAX_PATH + 1]; +static char Spaces[] = " "; + +static BOOL ErrorFlag; +static TCHAR ErrorContext[MAX_LOG_STR]; +static TCHAR ErrorCategory[MAX_LOG_STR]; +static TCHAR ErrorItem[MAX_LOG_STR]; +static TCHAR ErrorText[MAX_LOG_STR]; +static TCHAR tmpStr[MAX_LOG_STR]; +static BOOL CategoryWritten; +static BOOL ContextWritten; +static BOOL CategorySet; +static BOOL ItemSet; + +static BOOL VerboseULogging = TRUE; +static BOOL VerboseFLogging = TRUE; +static BOOL ErrorBreak = FALSE; + +static BOOL LogCancel = FALSE; + +/*+-------------------------------------------------------------------------+ + | ErrorResetAll() + | + +-------------------------------------------------------------------------+*/ +void ErrorResetAll() { + ErrorFlag = FALSE; + CategoryWritten = FALSE; + ContextWritten = FALSE; + CategorySet = FALSE; + ItemSet = FALSE; + + lstrcpy(ErrorContext, TEXT("")); + lstrcpy(ErrorCategory, TEXT("")); + +} // ErrorResetAll + + +/*+-------------------------------------------------------------------------+ + | ErrorContextSet() + | + | Sets the context for the error message, generally this would be + | the source and destination server pair. + | + +-------------------------------------------------------------------------+*/ +void ErrorContextSet(LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + wvsprintf(ErrorContext, szFormat, marker); + + // Do category and item as well since context is higher level + lstrcpy(ErrorCategory, TEXT("")); + lstrcpy(ErrorItem, TEXT("")); + + ContextWritten = FALSE; + CategoryWritten = FALSE; + va_end(marker); + +} // ErrorContextSet + + +/*+-------------------------------------------------------------------------+ + | ErrorCategorySet() + | + | Sets the category for the error message, generally this would tell + | what type of items is being converted: "Converting Users" + | + +-------------------------------------------------------------------------+*/ +void ErrorCategorySet(LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + wvsprintf(ErrorCategory, szFormat, marker); + CategorySet = TRUE; + ItemSet = FALSE; + lstrcpy(ErrorItem, TEXT("")); + CategoryWritten = FALSE; + va_end(marker); + +} // ErrorCategorySet + + +/*+-------------------------------------------------------------------------+ + | ErrorItemSet() + | + | Defines the specific item that error'd. This is usually a user, + | group or file name. + | + +-------------------------------------------------------------------------+*/ +void ErrorItemSet(LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + ItemSet = TRUE; + wvsprintf(ErrorItem, szFormat, marker); + va_end(marker); + +} // ErrorItemSet + + +/*+-------------------------------------------------------------------------+ + | ErrorReset() + | + +-------------------------------------------------------------------------+*/ +void ErrorReset() { + ErrorFlag = FALSE; + lstrcpy(ErrorText, TEXT("")); + +} // ErrorReset + + +/*+-------------------------------------------------------------------------+ + | ErrorSet() + | + +-------------------------------------------------------------------------+*/ +void ErrorSet(LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + wvsprintf(ErrorText, szFormat, marker); + ErrorFlag = TRUE; + va_end(marker); + +} // ErrorSet + + +BOOL ErrorOccured() { + return ErrorFlag; + +} // ErrorOccured + + +/*+-------------------------------------------------------------------------+ + | ErrorBox() + | + +-------------------------------------------------------------------------+*/ +void ErrorBox(LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + wvsprintf(ErrorText, szFormat, marker); + + MessageBeep(MB_ICONASTERISK); + MessageBox(NULL, ErrorText, (LPTSTR) Lids(IDS_E_2), MB_TASKMODAL | MB_ICONEXCLAMATION | MB_OK); + + va_end(marker); +} // ErrorBox + + +/*+-------------------------------------------------------------------------+ + | ErrorBoxRetry() + | + +-------------------------------------------------------------------------+*/ +int ErrorBoxRetry(LPTSTR szFormat, ...) { + int ret; + LPVOID lpMessageBuffer; + va_list marker; + + va_start(marker, szFormat); + wvsprintf(ErrorText, szFormat, marker); + + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), 0, + (LPTSTR) &lpMessageBuffer, 0, NULL ); + + MessageBeep(MB_ICONASTERISK); + ret = MessageBox(NULL, (LPTSTR) lpMessageBuffer, ErrorText, + MB_TASKMODAL | MB_ICONEXCLAMATION | MB_RETRYCANCEL); + LocalFree(lpMessageBuffer); + + va_end(marker); + + return ret; +} // ErrorBoxRetry + + +/*+-------------------------------------------------------------------------+ + | FileOpenBackup() + | + | Tries to open a file, if it already exists then creates a backup + | with the extension in the form (.001 to .999). It tries .001 first + | and if already used then tries .002, etc... + | + +-------------------------------------------------------------------------+*/ +HANDLE FileOpenBackup(CHAR *FileRoot, CHAR *FileExt) { + int ret; + HANDLE hFile = NULL; + DWORD dwFileNumber; + char FileName[MAX_PATH + 1]; + char buffer[MAX_PATH + 1]; + TCHAR FileNameW[MAX_PATH + 1]; + + wsprintfA(FileName, "%s%s", FileRoot, FileExt); + + // Open, but fail if already exists. + hFile = CreateFileA( FileName, GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); + + // Check if Error - file exists + if(hFile == INVALID_HANDLE_VALUE) { + dwFileNumber = 0; + + // Find next backup number... + // Files are backed up as .xxx where xxx is a number in the form .001, + // the first backup is stored as .001, second as .002, etc... + do { + dwFileNumber++; + wsprintfA(FileName, "%s%03u", FileRoot, dwFileNumber); + + hFile = CreateFileA( FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile != (HANDLE) INVALID_HANDLE_VALUE) + CloseHandle( hFile ); + + } while ( (hFile != INVALID_HANDLE_VALUE) ); + + // Rename the last log file to the first available number + wsprintfA( buffer, "%s%s", FileRoot, FileExt); + MoveFileA( buffer, FileName); + + lstrcpyA(FileName, buffer); + // Create the new log file + hFile = CreateFileA( FileName, GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); + + + if (hFile != (HANDLE) INVALID_HANDLE_VALUE) + CloseHandle( hFile ); + + } else + CloseHandle(hFile); + + wsprintfA(FileName, "%s%s", FileRoot, FileExt); + + // Now do the actual creation with error handling... + do { + ret = IDOK; + hFile = CreateFileA( FileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile == INVALID_HANDLE_VALUE) { + MultiByteToWideChar(CP_ACP, 0, FileName, -1, FileNameW, sizeof(FileNameW) ); + ret = ErrorBoxRetry(Lids(IDS_E_13), FileNameW); + } + + } while(ret == IDRETRY); + + return(hFile); + +} // FileOpenBackup + + +/*+-------------------------------------------------------------------------+ + | GetTime() + | + +-------------------------------------------------------------------------+*/ +void GetTime(TCHAR *str) { + SYSTEMTIME st; + static TCHAR *aszDay[7]; + + aszDay[0] = Lids(IDS_SUNDAY); + aszDay[1] = Lids(IDS_MONDAY); + aszDay[2] = Lids(IDS_TUESDAY); + aszDay[3] = Lids(IDS_WEDNESDAY); + aszDay[4] = Lids(IDS_THURSDAY); + aszDay[5] = Lids(IDS_FRIDAY); + aszDay[6] = Lids(IDS_SATURDAY); + + GetLocalTime(&st); + + wsprintf(str, TEXT("%s, %02u/%02u/%4u (%02u:%02u:%02u)"), + aszDay[st.wDayOfWeek], st.wMonth, + st.wDay, st.wYear, + st.wHour, st.wMinute, st.wSecond); +} // GetTime + + +/*+-------------------------------------------------------------------------+ + | WriteLog() + | + +-------------------------------------------------------------------------+*/ +DWORD WriteLog(HANDLE hFile, int Level, LPTSTR String) { + int ret; + DWORD wrote; + static char tmpStr[MAX_LOG_STR]; + static char LogStr[MAX_LOG_STR]; + + // If the user canceled writing to the log, then don't keep trying + if (LogCancel) + return 1; + + // Put ending NULL at correct place + Spaces[Level * 3] = '\0'; + + // Build up indented ANSI string to write out + lstrcpyA(tmpStr, Spaces); + WideCharToMultiByte(CP_ACP, 0, String, -1, LogStr, sizeof(LogStr), NULL, NULL); + lstrcatA(tmpStr, LogStr); + + // reset for later writes + Spaces[Level * 3] = ' '; + + + // Now do the actual write with error handling... + do { + ret = IDOK; + + if (!WriteFile(hFile, tmpStr, strlen(tmpStr), &wrote, NULL)) { + ret = ErrorBoxRetry(Lids(IDS_E_NWLOG)); + } + + } while(ret == IDRETRY); + + if (ret == IDCANCEL) { + LogCancel = TRUE; + return 1; + } + else + return 0; + +} // WriteLog + + +/*+-------------------------------------------------------------------------+ + | LogHeader() + | + +-------------------------------------------------------------------------+*/ +void LogHeader(HANDLE hFile, TCHAR *Title) { + DWORD ret; + DWORD wrote; + static TCHAR time[40]; + static TCHAR tmpStr[MAX_LOG_STR]; + static TCHAR tmpStr2[MAX_LOG_STR]; + static TCHAR *line; + + ret = WriteLog(hFile, 0, Lids(IDS_LINE)); + wsprintf(tmpStr, Lids(IDS_BRACE), Title); + + if (!ret) + ret = WriteLog(hFile, 0, tmpStr); + + if (!ret) + ret = WriteLog(hFile, 0, Lids(IDS_LINE)); + + GetTime(time); + wsprintf(tmpStr, Lids(IDS_L_97), time); + + if (!ret) + ret = WriteLog(hFile, 0, tmpStr); + + wrote = sizeof(tmpStr2); + GetComputerName(tmpStr2, &wrote); + wsprintf(tmpStr, Lids(IDS_L_98), tmpStr2); + + if (!ret) + WriteLog(hFile, 0, tmpStr); + + wrote = sizeof(tmpStr); + WNetGetUser(NULL, tmpStr2, &wrote); + wsprintf(tmpStr, Lids(IDS_L_99), tmpStr2); + + if (!ret) + ret = WriteLog(hFile, 0, tmpStr); + + wsprintf(tmpStr, Lids(IDS_L_100), VER_HI, VER_LOW); + + if (!ret) + ret = WriteLog(hFile, 0, tmpStr); + + if (!ret) + ret = WriteLog(hFile, 0, Lids(IDS_LINE)); + +} // LogHeader + + +/*+-------------------------------------------------------------------------+ + | LogInit() + | + +-------------------------------------------------------------------------+*/ +void LogInit() { + lstrcpyA(LogFileName, FILENAME_LOG); + lstrcpyA(ErrorLogFileName, FILENAME_ERROR); + lstrcpyA(SummaryLogFileName, FILENAME_SUMMARY); + + LogCancel = FALSE; + + hErr = FileOpenBackup(ERR_FILENAME, STD_EXT); + hLog = FileOpenBackup(LOG_FILENAME, STD_EXT); + hSummary = FileOpenBackup(SUMMARY_FILENAME, STD_EXT); + + LogHeader(hErr, Lids(IDS_L_101)); + CloseHandle(hErr); + + LogHeader(hLog, Lids(IDS_L_102)); + CloseHandle(hLog); + + LogHeader(hSummary, Lids(IDS_L_103)); + CloseHandle(hSummary); + +} // LogInit + + +/*+-------------------------------------------------------------------------+ + | LogWriteLog() + | + +-------------------------------------------------------------------------+*/ +void LogWriteLog(int Level, LPTSTR szFormat, ...) { + va_list marker; + + va_start(marker, szFormat); + wvsprintf(tmpStr, szFormat, marker); + + hLog = CreateFileA( LogFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + SetFilePointer(hLog, 0, NULL, FILE_END); + WriteLog(hLog, Level, tmpStr); + CloseHandle(hLog); + va_end(marker); + +} // LogWriteLog + + +/*+-------------------------------------------------------------------------+ + | LogWritErr() + | + +-------------------------------------------------------------------------+*/ +void LogWriteErr(LPTSTR szFormat, ...) { + int Indent = 3; + DWORD wrote; + static char LogStr[MAX_LOG_STR]; + va_list marker; + + va_start(marker, szFormat); + wvsprintf(tmpStr, szFormat, marker); + + hErr = CreateFileA( ErrorLogFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + SetFilePointer(hErr, 0, NULL, FILE_END); + + if (!ContextWritten) { + ContextWritten = TRUE; + WideCharToMultiByte(CP_ACP, 0, ErrorContext, -1, LogStr, sizeof(LogStr), NULL, NULL); + WriteFile(hErr, LogStr, strlen(LogStr), &wrote, NULL); + } + + if (CategorySet && !CategoryWritten) { + CategoryWritten = TRUE; + Spaces[3] = '\0'; + WriteFile(hLog, Spaces, strlen(Spaces), &wrote, NULL); + WideCharToMultiByte(CP_ACP, 0, ErrorCategory, -1, LogStr, sizeof(LogStr), NULL, NULL); + WriteFile(hErr, LogStr, strlen(LogStr), &wrote, NULL); + Spaces[3] = ' '; + } + + if (ItemSet) { + Spaces[6] = '\0'; + WriteFile(hLog, Spaces, strlen(Spaces), &wrote, NULL); + WideCharToMultiByte(CP_ACP, 0, ErrorItem, -1, LogStr, sizeof(LogStr), NULL, NULL); + WriteFile(hErr, LogStr, strlen(LogStr), &wrote, NULL); + Spaces[6] = ' '; + } + + if (CategorySet) + Indent +=3; + + if (ItemSet) + Indent +=3; + + Spaces[Indent] = '\0'; + WriteFile(hLog, Spaces, strlen(Spaces), &wrote, NULL); + WideCharToMultiByte(CP_ACP, 0, tmpStr, -1, LogStr, sizeof(LogStr), NULL, NULL); + WriteFile(hErr, LogStr, strlen(LogStr), &wrote, NULL); + Spaces[Indent] = ' '; + CloseHandle(hErr); + va_end(marker); + +} // LogWriteErr + + +/*+-------------------------------------------------------------------------+ + | LogWriteSummary() + | + +-------------------------------------------------------------------------+*/ +void LogWriteSummary(int Level, LPTSTR szFormat, ...) { + DWORD wrote; + static char LogStr[MAX_LOG_STR]; + va_list marker; + + va_start(marker, szFormat); + Spaces[Level * 3] = '\0'; + wvsprintf(tmpStr, szFormat, marker); + WideCharToMultiByte(CP_ACP, 0, tmpStr, -1, LogStr, sizeof(LogStr), NULL, NULL); + + hSummary = CreateFileA( SummaryLogFileName, GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + SetFilePointer(hSummary, 0, NULL, FILE_END); + WriteFile(hLog, Spaces, strlen(Spaces), &wrote, NULL); + WriteFile(hSummary, LogStr, strlen(LogStr), &wrote, NULL); + Spaces[Level * 3] = ' '; + CloseHandle(hSummary); + va_end(marker); + +} // LogWriteSummary + + + +/*+-------------------------------------------------------------------------+ + | DlgLogging() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgLogging(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HANDLE hFile; + static BOOL UserLogging, FileLogging, ErrorFlag; + int wmId, wmEvent; + static char CmdLine[256]; + HWND hCtrl; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // Toggle User Logging Control + UserLogging = VerboseULogging; + hCtrl = GetDlgItem(hDlg, IDC_CHKUVERBOSE); + if (VerboseULogging) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + // Toggle File Logging Control + FileLogging = VerboseFLogging; + hCtrl = GetDlgItem(hDlg, IDC_CHKFVERBOSE); + if (VerboseFLogging) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + // Toggle Error Popup Control + ErrorFlag = ErrorBreak; + hCtrl = GetDlgItem(hDlg, IDC_CHKERROR); + if (ErrorBreak) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + hCtrl = GetDlgItem(hDlg, IDC_VIEWLOG); + + // check if logfile exists, if it does allow log file viewing... + hFile = CreateFileA( FILENAME_LOG, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile != (HANDLE) INVALID_HANDLE_VALUE) + CloseHandle( hFile ); + else + EnableWindow(hCtrl, FALSE); + + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + VerboseULogging = UserLogging; + VerboseFLogging = FileLogging; + ErrorBreak = ErrorFlag; + EndDialog(hDlg, 0); + return (TRUE); + break; + + case IDCANCEL: + EndDialog(hDlg, 0); + return (TRUE); + + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_LOGGING); + break; + + case IDC_VIEWLOG: + lstrcpyA(CmdLine, "LogView "); + lstrcatA(CmdLine, "Error.LOG Summary.LOG LogFile.LOG"); + WinExec(CmdLine, SW_SHOW); + return (TRUE); + break; + + case IDC_CHKUVERBOSE: + UserLogging = !UserLogging; + return (TRUE); + break; + + case IDC_CHKFVERBOSE: + FileLogging = !FileLogging; + return (TRUE); + break; + + case IDC_CHKERROR: + ErrorFlag = !ErrorFlag; + return (TRUE); + break; + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgLogging + + +/*+-------------------------------------------------------------------------+ + | LogOptionsInit() + | + +-------------------------------------------------------------------------+*/ +void LogOptionsInit() { + ErrorBreak = FALSE; + VerboseULogging = TRUE; + VerboseFLogging = FALSE; +} // LogOptionsInit + + +/*+-------------------------------------------------------------------------+ + | LogOptionsSave() + | + +-------------------------------------------------------------------------+*/ +void LogOptionsSave( HANDLE hFile ) { + DWORD wrote; + + WriteFile(hFile, &ErrorBreak, sizeof(ErrorBreak), &wrote, NULL); + WriteFile(hFile, &VerboseFLogging, sizeof(VerboseFLogging), &wrote, NULL); + WriteFile(hFile, &VerboseULogging, sizeof(VerboseULogging), &wrote, NULL); +} // LogOptionsSave + + +/*+-------------------------------------------------------------------------+ + | LogOptionsLoad() + | + +-------------------------------------------------------------------------+*/ +void LogOptionsLoad( HANDLE hFile ) { + DWORD wrote; + + ReadFile(hFile, &ErrorBreak, sizeof(ErrorBreak), &wrote, NULL); + ReadFile(hFile, &VerboseFLogging, sizeof(VerboseFLogging), &wrote, NULL); + ReadFile(hFile, &VerboseULogging, sizeof(VerboseULogging), &wrote, NULL); + +#ifdef DEBUG +dprintf(TEXT("\n")); +dprintf(TEXT(" Error Break: %lx\n"), ErrorBreak); +dprintf(TEXT(" Verbose File Logging: %lx\n"), VerboseFLogging); +dprintf(TEXT(" Verbose User Logging: %lx\n\n"), VerboseULogging); +#endif +} // LogOptionsLoad + + +/*+-------------------------------------------------------------------------+ + | PopupOnError() + | + +-------------------------------------------------------------------------+*/ +BOOL PopupOnError() { + return ErrorBreak; + +} // PopupOnError + + +/*+-------------------------------------------------------------------------+ + | VerboseFileLogging() + | + +-------------------------------------------------------------------------+*/ +BOOL VerboseFileLogging() { + return VerboseFLogging; + +} // VerboseFileLogging + + +/*+-------------------------------------------------------------------------+ + | VerboseUserLogging() + | + +-------------------------------------------------------------------------+*/ +BOOL VerboseUserLogging() { + return VerboseULogging; + +} // VerboseUserLogging + + +/*+-------------------------------------------------------------------------+ + | DoLoggingDlg() + | + +-------------------------------------------------------------------------+*/ +void DoLoggingDlg(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC)DlgLogging, hInst); + DialogBox(hInst, TEXT("DlgLogging"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // DoLoggingDlg diff --git a/private/nw/convert/nwconv/nwlog.h b/private/nw/convert/nwconv/nwlog.h new file mode 100644 index 000000000..ceb44e407 --- /dev/null +++ b/private/nw/convert/nwconv/nwlog.h @@ -0,0 +1,39 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _NWLOG_ +#define _NWLOG_ + +#ifdef __cplusplus +extern "C"{ +#endif + +void LogInit(); +void LogWriteLog(int Level, LPTSTR szFormat, ...); +void LogWriteErr(LPTSTR szFormat, ...); +void LogWriteSummary(int Level, LPTSTR szFormat, ...); +void GetTime(TCHAR *str); +void ErrorResetAll(); +void ErrorContextSet(LPTSTR szFormat, ...); +void ErrorCategorySet(LPTSTR szFormat, ...); +void ErrorItemSet(LPTSTR szFormat, ...); +void ErrorReset(); +void ErrorSet(LPTSTR szFormat, ...); +BOOL ErrorOccured(); +void ErrorBox(LPTSTR szFormat, ...); +int ErrorBoxRetry(LPTSTR szFormat, ...); + +void LogOptionsInit(); +void LogOptionsSave( HANDLE hFile ); +void LogOptionsLoad( HANDLE hFile ); +BOOL PopupOnError(); +BOOL VerboseFileLogging(); +BOOL VerboseUserLogging(); +void DoLoggingDlg(HWND hDlg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/nwnetapi.c b/private/nw/convert/nwconv/nwnetapi.c new file mode 100644 index 000000000..2815484ee --- /dev/null +++ b/private/nw/convert/nwconv/nwnetapi.c @@ -0,0 +1,2692 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation + +Module Name: + + nwnetapi.c + +Abstract: + + +Author: + + Arthur Hanson (arth) 16-Jun-1994 + +Revision History: + +--*/ + + +#include "globals.h" + +#include +#include "nwconv.h" +#include "convapi.h" +#include "nwnetapi.h" +#include "statbox.h" + +#define SUPERVISOR "SUPERVISOR" +#define ACCOUNT_LOCKOUT "ACCT_LOCKOUT" +#define GROUP_MEMBERS "GROUP_MEMBERS" +#define GROUPS_IM_IN "GROUPS_I'M_IN" +#define IDENTIFICATION "IDENTIFICATION" +#define LOGIN_CONTROL "LOGIN_CONTROL" +#define PS_OPERATORS "PS_OPERATORS" +#define SECURITY_EQUALS "SECURITY_EQUALS" +#define USER_DEFAULTS "USER_DEFAULTS" +#define MS_EXTENDED_NCPS "MS_EXTENDED_NCPS" +#define FPNW_PDC "FPNWPDC" + +#ifdef DEBUG +int ErrorBoxRetry(LPTSTR szFormat, ...); +#endif + +// Couple of NetWare specific data structures - see NetWare programming books for +// info on these structures +#pragma pack(1) +typedef struct tagLoginControl { + BYTE byAccountExpires[3]; + BYTE byAccountDisabled; + BYTE byPasswordExpires[3]; + BYTE byGraceLogins; + WORD wPasswordInterval; + BYTE byGraceLoginReset; + BYTE byMinPasswordLength; + WORD wMaxConnections; + BYTE byLoginTimes[42]; + BYTE byLastLogin[6]; + BYTE byRestrictions; + BYTE byUnused; + long lMaxDiskBlocks; + WORD wBadLogins; + LONG lNextResetTime; + BYTE byBadLoginAddr[12]; +}; // tagLoginControl +#pragma pack() + + +typedef struct tagAccountBalance { + long lBalance; + long lCreditLimit; +}; // tagAccountBalance + + +typedef struct tagUserDefaults { + BYTE byAccountExpiresYear; + BYTE byAccountExpiresMonth; + BYTE byAccountExpiresDay; + BYTE byRestrictions; + WORD wPasswordInterval; + BYTE byGraceLoginReset; + BYTE byMinPasswordLength; + WORD wMaxConnections; + BYTE byLoginTimes[42]; + long lBalance; + long lCreditLimit; + long lMaxDiskBlocks; +}; // tagUserDefaults + + +// define the mapping for FILE objects. Note: we only use GENERIC and +// STANDARD bits! +RIGHTS_MAPPING FileRightsMapping = { + 0, + { FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS + }, + { { NW_FILE_READ, GENERIC_READ}, + { NW_FILE_WRITE, GENERIC_WRITE}, + { NW_FILE_CREATE, 0}, + { NW_FILE_DELETE, GENERIC_WRITE|DELETE}, + { NW_FILE_PERM, WRITE_DAC}, + { NW_FILE_SCAN, 0}, + { NW_FILE_MODIFY, GENERIC_WRITE}, + { NW_FILE_SUPERVISOR, GENERIC_ALL}, + { 0, 0 } + } +} ; + +RIGHTS_MAPPING DirRightsMapping = { + CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, + { FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS + }, + { { NW_FILE_READ, GENERIC_READ|GENERIC_EXECUTE}, + { NW_FILE_WRITE, GENERIC_WRITE}, + { NW_FILE_CREATE, GENERIC_WRITE}, + { NW_FILE_DELETE, DELETE}, + { NW_FILE_PERM, WRITE_DAC}, + { NW_FILE_SCAN, GENERIC_READ}, + { NW_FILE_MODIFY, GENERIC_WRITE}, + { NW_FILE_SUPERVISOR, GENERIC_ALL}, + { 0, 0 } + } +} ; + +VOID UserInfoLog(LPTSTR UserName, struct tagLoginControl tag); +VOID Moveit(NWCONN_HANDLE Conn, LPTSTR UserName); +VOID UserRecInit(NT_USER_INFO *UserInfo); +BOOL IsNCPServerFPNW(NWCONN_HANDLE Conn); + +static NWCONN_HANDLE CachedConn = 0; + +static TCHAR CachedServer[MAX_SERVER_NAME_LEN + 1]; +static DWORD CachedServerTime = 0xffffffff; // minutes since 1985... + +typedef struct _PRINT_SERVER_BUFFER { + TCHAR Name[20]; +} PRINT_SERVER_BUFFER; + +typedef struct _PRINT_SERVER_LIST { + ULONG Count; + PRINT_SERVER_BUFFER PSList[]; +} PRINT_SERVER_LIST; + + + +///////////////////////////////////////////////////////////////////////// +int +NWGetMaxServerNameLen() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + return MAX_SERVER_NAME_LEN; + +} // NWGetMaxServerNameLen + + +///////////////////////////////////////////////////////////////////////// +int +NWGetMaxUserNameLen() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + return MAX_USER_NAME_LEN; + +} // NWGetMaxUserNameLen + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWServerFree() + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + + if (CachedConn) + NWDetachFromFileServer(CachedConn); + + CachedConn = 0; + + return (0); + +} // NWServerFree + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWServerSet( + LPTSTR FileServer + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + NWLOCAL_SCOPE ScopeFlag = 0; + NWCONN_HANDLE Conn = 0; + NWCCODE ret = 0; + char szAnsiFileServer[MAX_SERVER_NAME_LEN + 1]; + + NWServerFree(); + + lstrcpy(CachedServer, FileServer); + CharToOem(FileServer, szAnsiFileServer); + + ret = NWAttachToFileServer(szAnsiFileServer, ScopeFlag, &Conn); + + if (!ret) { + CachedConn = Conn; + NWServerTimeGet(); + } + + return ((DWORD) ret); + +} // NWServerSet + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUseDel( + LPTSTR ServerName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR LocServer[MAX_SERVER_NAME_LEN+3]; + + NWServerFree(); + wsprintf(LocServer, Lids(IDS_S_27), ServerName); + WNetCancelConnection2(LocServer, 0, FALSE); + +} // NWUseDel + + +///////////////////////////////////////////////////////////////////////// +BOOL +NWUserNameValidate( + LPTSTR szUserName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR UserName[MAX_USER_NAME_LEN + 1]; + DWORD Size; + + // if same as logged on user then don't convert or overwrite + Size = sizeof(UserName); + WNetGetUser(NULL, UserName, &Size); + if (!lstrcmpi(szUserName, UserName)) + return FALSE; + + // Now check for other special names + if (!lstrcmpi(szUserName, Lids(IDS_S_28))) + return FALSE; + + if (!lstrcmpi(szUserName, Lids(IDS_S_29))) + return FALSE; + + if (!lstrcmpi(szUserName, Lids(IDS_S_30))) + return FALSE; + + return TRUE; + +} // NWUserNameValidate + + +///////////////////////////////////////////////////////////////////////// +BOOL +NWGroupNameValidate( + LPTSTR szGroupName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + + if (!lstrcmpi(szGroupName, Lids(IDS_S_31))) + return FALSE; + + if (!lstrcmpi(szGroupName, Lids(IDS_S_28))) + return FALSE; + + return TRUE; + +} // NWGroupNameValidate + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +NWSpecialNamesMap( + LPTSTR Name + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + ULONG i; + static BOOL InitStrings = FALSE; + static LPTSTR SpecialNames[5]; + static LPTSTR SpecialMap[5]; + + if (!InitStrings) { + InitStrings = TRUE; + SpecialNames[0] = Lids(IDS_S_28); + SpecialNames[1] = Lids(IDS_S_30); + SpecialNames[2] = Lids(IDS_S_31); + SpecialNames[3] = Lids(IDS_S_29); + SpecialNames[4] = NULL; + + SpecialMap[0] = Lids(IDS_S_32); + SpecialMap[1] = Lids(IDS_S_32); + SpecialMap[2] = Lids(IDS_S_33); + SpecialMap[3] = Lids(IDS_S_29); + SpecialMap[4] = NULL; + } + + i = 0; + while(SpecialNames[i] != NULL) { + if (!lstrcmpi(SpecialNames[i], Name)) { + return SpecialMap[i]; + } + + i++; + } + + return Name; + +} // NWSpecialNamesMap + + +///////////////////////////////////////////////////////////////////////// +BOOL +NWIsAdmin( + LPTSTR UserName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + char szAnsiUserName[MAX_USER_NAME_LEN]; + NWCCODE ret; + + CharToOem(UserName, szAnsiUserName); + ret = NWIsObjectInSet(CachedConn, szAnsiUserName, OT_USER, SECURITY_EQUALS, + SUPERVISOR, OT_USER); + + if (ret == SUCCESSFUL) + return TRUE; + else + return FALSE; + +} // NWIsAdmin + + +///////////////////////////////////////////////////////////////////////// +BOOL +NWObjectNameGet( + DWORD ObjectID, + LPTSTR ObjectName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + char szAnsiObjectName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + NWCCODE ret; + + lstrcpy(ObjectName, TEXT("")); + + if (!(ret = NWGetObjectName(CachedConn, ObjectID, szAnsiObjectName, &wFoundUserType))) { + + // + // Got user - now convert and save off the information + // + OemToChar(szAnsiObjectName, ObjectName); + } + + if (ret == SUCCESSFUL) + return TRUE; + else + return FALSE; + +} // NWObjectNameGet + + +#define DEF_NUM_RECS 200 +///////////////////////////////////////////////////////////////////////// +DWORD +NWUsersEnum( + USER_LIST **lpUsers, + BOOL Display + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + USER_LIST *Users = NULL; + USER_BUFFER *UserBuffer = NULL; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD status = 0; + char szAnsiUserName[MAX_USER_NAME_LEN + 1]; + TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + DWORD dwObjectID = 0xFFFFFFFFL; + BYTE byPropertiesFlag = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + NWCCODE ret; + + if (Display) + Status_ItemLabel(Lids(IDS_S_44)); + + Users = (USER_LIST *) AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = Users->UserBuffer; + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiUserName, ""); + + // Loop through bindery getting all the users. + while ((ret = NWScanObject(CachedConn, "*", OT_USER, &dwObjectID, szAnsiUserName, + &wFoundUserType, &byPropertiesFlag, + &byObjectFlag, &byObjectSecurity)) == SUCCESSFUL) { + + // Got user - now convert and save off the information + OemToChar(szAnsiUserName, szUserName); + + if (NWUserNameValidate(szUserName)) { + if (Display) + Status_Item(szUserName); + + lstrcpy(UserBuffer[Count].Name, szUserName); + lstrcpy(UserBuffer[Count].NewName, szUserName); + Count++; + } + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + UserBuffer = Users->UserBuffer; + } + + } + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER)* Count)); + + if (!Users) + status = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + UserBuffer = Users->UserBuffer; + qsort((void *) UserBuffer, (size_t) Count, sizeof(USER_BUFFER), UserListCompare); + } + } + + if (Users != NULL) + Users->Count = Count; + + *lpUsers = Users; + + return status; + +} // NWUsersEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWGroupsEnum( + GROUP_LIST **lpGroups, + BOOL Display + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + GROUP_LIST *Groups = NULL; + GROUP_BUFFER *GroupBuffer; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD status = 0; + char szAnsiGroupName[MAX_GROUP_NAME_LEN + 1]; + TCHAR szGroupName[MAX_GROUP_NAME_LEN + 1]; + WORD wFoundGroupType = 0; + DWORD dwObjectID = 0xFFFFFFFFL; + BYTE byPropertiesFlag = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + NWCCODE ret; + + if (Display) + Status_ItemLabel(Lids(IDS_S_45)); + + Groups = (GROUP_LIST *) AllocMemory(sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER) * NumRecs)); + + if (!Groups) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + GroupBuffer = Groups->GroupBuffer; + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiGroupName, ""); + + // Loop through bindery getting all the users. + while ((ret = NWScanObject(CachedConn, "*", OT_USER_GROUP, &dwObjectID, szAnsiGroupName, + &wFoundGroupType, &byPropertiesFlag, + &byObjectFlag, &byObjectSecurity)) == SUCCESSFUL) { + + // Got user - now convert and save off the information + OemToChar(szAnsiGroupName, szGroupName); + + if (NWGroupNameValidate(szGroupName)) { + if (Display) + Status_Item(szGroupName); + + lstrcpy(GroupBuffer[Count].Name, szGroupName); + lstrcpy(GroupBuffer[Count].NewName, szGroupName); + Count++; + } + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Groups = (GROUP_LIST *) ReallocMemory((HGLOBAL) Groups, sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER) * NumRecs)); + + if (!Groups) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + GroupBuffer = Groups->GroupBuffer; + } + + } + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + Groups = (GROUP_LIST *) ReallocMemory((HGLOBAL) Groups, sizeof(GROUP_LIST) + (sizeof(GROUP_BUFFER) * Count)); + + if (!Groups) + status = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + GroupBuffer = Groups->GroupBuffer; + qsort((void *) GroupBuffer, (size_t) Count, sizeof(GROUP_BUFFER), UserListCompare); + } + } + + if (Groups != NULL) + Groups->Count = Count; + + *lpGroups = Groups; + + return status; + +} // NWGroupsEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWGroupUsersEnum( + LPTSTR GroupName, + USER_LIST **lpUsers + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + USER_LIST *Users = NULL; + USER_BUFFER *UserBuffer; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD i = 0; + DWORD status = 0; + char szAnsiUserName[MAX_USER_NAME_LEN + 1]; + char szAnsiGroupName[MAX_GROUP_NAME_LEN + 1]; + TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + BYTE byPropertyFlags = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + UCHAR Segment = 1; + DWORD bySegment[32]; + BYTE byMoreSegments; + NWCCODE ret; + + Users = (USER_LIST *) AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = Users->UserBuffer; + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiUserName, ""); + CharToOem(GroupName, szAnsiGroupName); + + // Loop through bindery getting all the users. + do { + if (!(ret = NWReadPropertyValue(CachedConn, szAnsiGroupName, OT_USER_GROUP, GROUP_MEMBERS, + Segment, (BYTE *) bySegment, &byMoreSegments, &byPropertyFlags))) { + + Segment++; + // loop through properties converting them to user names + i = 0; + while ((bySegment[i]) && (i < 32)) { + if (!(ret = NWGetObjectName(CachedConn, bySegment[i], szAnsiUserName, &wFoundUserType))) { + // Got user - now convert and save off the information + OemToChar(szAnsiUserName, szUserName); + + lstrcpy(UserBuffer[Count].Name, szUserName); + lstrcpy(UserBuffer[Count].NewName, szUserName); + Count++; + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + UserBuffer = Users->UserBuffer; + } + } + i++; + } + + } else // if NWReadPropertyValue + byMoreSegments = 0; + + } while (byMoreSegments); + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * Count)); + + if (!Users) + status = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + UserBuffer = Users->UserBuffer; + qsort((void *) UserBuffer, (size_t) Count, sizeof(USER_BUFFER), UserListCompare); + } + } + + if (Users != NULL) + Users->Count = Count; + + *lpUsers = Users; + + return status; + +} // NWGroupUsersEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWUserEquivalenceEnum( + LPTSTR UserName, + USER_LIST **lpUsers + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + USER_LIST *Users; + USER_BUFFER *UserBuffer; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD i = 0; + DWORD status = 0; + char szAnsiUserName[MAX_USER_NAME_LEN + 1]; + char szAnsiName[MAX_GROUP_NAME_LEN + 1]; + TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + DWORD dwObjectID = 0xFFFFFFFFL; + BYTE byPropertyFlags = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + UCHAR Segment = 1; + DWORD bySegment[32]; + BYTE byMoreSegments; + NWCCODE ret; + + Users = (USER_LIST *) AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = Users->UserBuffer; + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiUserName, ""); + CharToOem(UserName, szAnsiName); + + // Loop through bindery getting all the users. + do { + if (!(ret = NWReadPropertyValue(CachedConn, szAnsiName, OT_USER, SECURITY_EQUALS, + Segment, (BYTE *) bySegment, &byMoreSegments, &byPropertyFlags))) { + + Segment++; + // loop through properties converting them to user names + i = 0; + while ((bySegment[i]) && (i < 32)) { + if (!(ret = NWGetObjectName(CachedConn, bySegment[i], szAnsiUserName, &wFoundUserType))) { + // Got user - now convert and save off the information + OemToChar(szAnsiUserName, szUserName); + + // Map out Everyone equivalence + if (lstrcmpi(szUserName, Lids(IDS_S_31))) { + lstrcpy(UserBuffer[Count].Name, szUserName); + lstrcpy(UserBuffer[Count].NewName, szUserName); + Count++; + } + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + UserBuffer = Users->UserBuffer; + } + } + i++; + } + + } else // if NWReadPropertyValue + byMoreSegments = 0; + + } while (byMoreSegments); + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * Count)); + + if (!Users) + status = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + UserBuffer = Users->UserBuffer; + qsort((void *) UserBuffer, (size_t) Count, sizeof(USER_BUFFER), UserListCompare); + } + } + + if (Users != NULL) + Users->Count = Count; + + *lpUsers = Users; + + return status; + +} // NWUserEquivalenceEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWFileRightsEnum( + LPTSTR FileName, + USER_RIGHTS_LIST **lpUsers, + DWORD *UserCount, + BOOL DownLevel + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + BOOL Continue = TRUE; + USER_RIGHTS_LIST *Users = NULL; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD i = 0; + DWORD status = 0; + char szAnsiUserName[MAX_USER_NAME_LEN + 1]; + char szAnsiSearchDir[MAX_PATH + 1]; + TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + NWCCODE ret; + char FoundDir[16]; + ULONG Entries; + + TRUSTEE_INFO ti[20]; + BYTE DirHandle, nDirHandle; + BYTE Sequence; + BYTE NumEntries = 0; + NWDATE_TIME dtime = 0; + NWOBJ_ID ownerID = 0; + + if (DownLevel) { + Entries = 5; + Sequence = 1; + } else { + Entries = 20; + Sequence = 0; + } + + DirHandle = nDirHandle = 0; + memset(ti, 0, sizeof(ti)); + + Users = (USER_RIGHTS_LIST *) AllocMemory(NumRecs * sizeof(USER_RIGHTS_LIST)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiUserName, ""); + CharToOem(FileName, szAnsiSearchDir); + + // Loop through bindery getting all the users. + do { + if (DownLevel) + ret = NWCScanDirectoryForTrustees2(CachedConn, nDirHandle, szAnsiSearchDir, + &Sequence, FoundDir, &dtime, &ownerID, ti); + else + ret = NWCScanForTrustees(CachedConn, nDirHandle, szAnsiSearchDir, + &Sequence, &NumEntries, ti); + + if (!ret) { + // loop through properties converting them to user names + for (i = 0; i < Entries; i++) { + if (ti[i].objectID != 0) { + if (!(ret = NWGetObjectName(CachedConn, ti[i].objectID, szAnsiUserName, &wFoundUserType))) { + // Got user - now convert and save off the information + OemToChar(szAnsiUserName, szUserName); + + lstrcpy(Users[Count].Name, szUserName); + Users[Count].Rights = ti[i].objectRights; + Count++; + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Users = (USER_RIGHTS_LIST *) ReallocMemory((HGLOBAL) Users, NumRecs * sizeof(USER_RIGHTS_LIST)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + } // if realloc buffer + } + } // if objectID != 0 + } + + } else // NWScan failed + Continue = FALSE; + + } while (Continue); + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) { + status = ret; + + if (Users != NULL) { + FreeMemory(Users); + Count = 0; + } + } + + // Now slim down the list to just what we need. + if (!status) { + Users = (USER_RIGHTS_LIST *) ReallocMemory((HGLOBAL) Users, Count * sizeof(USER_RIGHTS_LIST)); + + if (!Users) + status = ERROR_NOT_ENOUGH_MEMORY; + else + // Sort the server list before putting it in the dialog + qsort((void *) Users, (size_t) Count, sizeof(USER_RIGHTS_LIST), UserListCompare); + } + + *UserCount = Count; + *lpUsers = Users; + + return status; + +} // NWFileRightsEnum + + +///////////////////////////////////////////////////////////////////////// +VOID +NWLoginTimesMap( + BYTE *Times, + BYTE *NewTimes + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD i, j; + int Bit = 0; + int Val; + BYTE BitSet; + + for (i = 0; i < 21; i++) { + BitSet = 0; + + for (j = 0; j < 8; j++) { + if (BitTest(Bit, Times) || BitTest(Bit+1, Times)) { + Val = 0x1 << j; + BitSet = BitSet + (BYTE) Val; + } + + Bit++; Bit++; + } + + NewTimes[i] = BitSet; + } + + +} // NWLoginTimesMap + + +/*+-------------------------------------------------------------------------+ + | Time Conversion | + +-------------------------------------------------------------------------+*/ + +#define IS_LEAP(y) ((y % 4 == 0) && (y % 100 != 0 || y % 400 == 0)) +#define DAYS_IN_YEAR(y) (IS_LEAP(y) ? 366 : 365) +#define DAYS_IN_MONTH(m,y) (IS_LEAP(y) ? _days_month_leap[m] : _days_month[m]) +#define SECS_IN_DAY (60L * 60L * 24L) +#define SECS_IN_HOUR (60L * 60L) +#define SECS_IN_MINUTE (60L) + +static short _days_month_leap[] = { 31,29,31,30,31,30,31,31,30,31,30,31 }; +static short _days_month[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; + +///////////////////////////////////////////////////////////////////////// +BOOL +NWTimeMap( + DWORD Days, + DWORD dwMonth, + DWORD dwYear, + DWORD dwBasis, + ULONG *Time + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD dw = 0; + DWORD dwDays = 0; + + // Zero + *Time = 0L; + + // Adjust year + if(dwYear < 70) + dwYear += 2000L; + else + if(dwYear < 100) + dwYear += 1900L; + + if (dwYear < dwBasis) + return FALSE; + + // Calculate days in previous years, take -1 so we skip current year + dw = dwYear - 1; + while(dw >= dwBasis) { + dwDays += DAYS_IN_YEAR(dw); + --dw; + } + + // Days from month + if((dwMonth < 1)||(dwMonth > 12)) + return FALSE; + + // Loop through adding number of days in each month. Take -2 (-1 to skip + // current month, and -1 to make 0 based). + dw = dwMonth; + while(dw > 1) { + dwDays += DAYS_IN_MONTH(dw-2, dwYear); + --dw; + } + + // Convert days + dw = Days; + if((dw >= 1) && (dw <= (DWORD) DAYS_IN_MONTH(dwMonth - 1, dwYear))) + dwDays += dw; + else + return FALSE; // out of range + + *Time += dwDays * SECS_IN_DAY; + return TRUE; +} // NWTimeMap + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +NWUserNameGet( + LPTSTR szUserName + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR UserName[128]; + char szAnsiUserName[MAX_USER_NAME_LEN]; + NWCCODE ret; + BYTE bySegment[128]; + BYTE byMoreSegments, byPropertyFlags; + LPSTR szAnsiFullName; + + CharToOem(szUserName, szAnsiUserName); + ret = NWReadPropertyValue(CachedConn, szAnsiUserName, OT_USER, IDENTIFICATION, + 1, bySegment, &byMoreSegments, &byPropertyFlags); + + if (ret == SUCCESSFUL) { + szAnsiFullName = (LPSTR) bySegment; + OemToChar(szAnsiFullName, UserName); + return UserName; + } + + return NULL; + +} // NWUserNameGet + + +///////////////////////////////////////////////////////////////////////// +VOID +NWNetUserMapInfo ( + LPTSTR szUserName, + VOID *UInfo, + NT_USER_INFO *NT_UInfo + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + ULONG expires; + struct tagLoginControl *tag; + LPTSTR FullName; + + tag = (struct tagLoginControl *) UInfo; + + FullName = NWUserNameGet(szUserName); + if (FullName != NULL) + lstrcpyn(NT_UInfo->full_name, FullName, MAXCOMMENTSZ); + + // Account disabled + if (tag->byAccountDisabled) + NT_UInfo->flags = NT_UInfo->flags | 0x02; + + // account locked out + if ((tag->wBadLogins == 0xffff) && + (tag->lNextResetTime > (LONG)CachedServerTime)) + NT_UInfo->flags = NT_UInfo->flags | 0x02; // disable account... + + // user can change password + if ((tag->byRestrictions & 0x01)) + NT_UInfo->flags = NT_UInfo->flags | 0x40; + + NWLoginTimesMap(tag->byLoginTimes, NT_UInfo->logon_hours); + + // account expires + if (tag->byAccountExpires[0] == 0) + NT_UInfo->acct_expires = TIMEQ_FOREVER; + else + if (tag->byAccountExpires[0] < 70) + NT_UInfo->acct_expires = 0; + else { + // fits within time range so convert to #seconds since 1970 + expires = 0; + NWTimeMap((DWORD) tag->byAccountExpires[2], + (DWORD) tag->byAccountExpires[1], + (DWORD) tag->byAccountExpires[0], 1970, &expires); + NT_UInfo->acct_expires = expires; + } + +} // NWNetUserMapInfo + + +///////////////////////////////////////////////////////////////////////// +VOID +NWFPNWMapInfo( + VOID *NWUInfo, + PFPNW_INFO fpnw + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + struct tagLoginControl *tag; + + tag = (struct tagLoginControl *) NWUInfo; + + fpnw->MaxConnections = tag->wMaxConnections; + fpnw->PasswordInterval = tag->wPasswordInterval; + fpnw->GraceLoginAllowed = tag->byGraceLogins; + fpnw->GraceLoginRemaining = tag->byGraceLoginReset; + fpnw->LoginFrom = NULL; + fpnw->HomeDir = NULL; + +} // NWFPNWMapInfo + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUserDefaultsGet( + VOID **UDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + struct tagUserDefaults *UserDefaults = NULL; + NWCCODE ret; + BYTE bySegment[128]; + BYTE byMoreSegments, byPropertyFlags; + + ret = NWReadPropertyValue(CachedConn, SUPERVISOR, OT_USER, USER_DEFAULTS, 1, bySegment, &byMoreSegments, &byPropertyFlags); + + if (ret == SUCCESSFUL) { + UserDefaults = AllocMemory(sizeof(struct tagUserDefaults)); + memcpy(UserDefaults, bySegment, sizeof (struct tagUserDefaults)); + + // Now put the data in 'normal' Intel format + SWAPBYTES(UserDefaults->wPasswordInterval); + SWAPBYTES(UserDefaults->wMaxConnections); + SWAPWORDS(UserDefaults->lBalance); + SWAPWORDS(UserDefaults->lCreditLimit); + SWAPWORDS(UserDefaults->lMaxDiskBlocks); + } + + *UDefaults = (void *) UserDefaults; + +} // NWUserDefaultsGet + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUserDefaultsMap( + VOID *NWUDefaults, + NT_DEFAULTS *NTDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + struct tagUserDefaults *UserDefaults = NULL; + + if ((NWUDefaults == NULL) || (NTDefaults == NULL)) + return; + + UserDefaults = (struct tagUserDefaults *) NWUDefaults; + + NTDefaults->min_passwd_len = (DWORD) UserDefaults->byMinPasswordLength; + NTDefaults->max_passwd_age = (DWORD) UserDefaults->wPasswordInterval * 86400; + NTDefaults->force_logoff = (DWORD) UserDefaults->byGraceLoginReset; + + // These fields aren't used/converted + // NTDefaults->min-passwd_age - no such thing for NetWare + // NTDefaults->password_hist_len - no such thing for NetWare + +} // NWUserDefaultsMap + + +///////////////////////////////////////////////////////////////////////// +VOID +NWLoginTimesLog( + BYTE *Times + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + TCHAR *szDays[7]; + DWORD Day; + DWORD Hours; + int Bit = 0, i; + static TCHAR szHours[80]; + + szDays[0] = Lids(IDS_SUN); + szDays[1] = Lids(IDS_MON); + szDays[2] = Lids(IDS_TUE); + szDays[3] = Lids(IDS_WED); + szDays[4] = Lids(IDS_THU); + szDays[5] = Lids(IDS_FRI); + szDays[6] = Lids(IDS_SAT); + + LogWriteLog(1, Lids(IDS_CRLF)); + LogWriteLog(1, Lids(IDS_L_104)); + + // while these should be level 2, there isn't room on 80 cols - so level 1 + LogWriteLog(1, Lids(IDS_L_1)); + LogWriteLog(1, Lids(IDS_L_2)); + LogWriteLog(1, Lids(IDS_L_3)); + + for (Day = 0; Day < 7; Day++) { + LogWriteLog(1, szDays[Day]); + lstrcpy(szHours, TEXT(" ")); + + for (Hours = 0; Hours < 24; Hours++) { + for (i = 0; i < 2; i++) { + if (BitTest(Bit, Times)) + lstrcat(szHours, TEXT("*")); + else + lstrcat(szHours, TEXT(" ")); + + Bit++; + } + + lstrcat(szHours, TEXT(" ")); + } + + LogWriteLog(0, szHours); + LogWriteLog(0, Lids(IDS_CRLF)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // NWLoginTimesLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUserDefaultsLog( + VOID *UDefaults + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + struct tagUserDefaults *tag; + + tag = (struct tagUserDefaults *) UDefaults; + + // Account expires + LogWriteLog(1, Lids(IDS_L_109)); + if (tag->byAccountExpiresYear == 0) + LogWriteLog(0, Lids(IDS_L_107)); + else + LogWriteLog(0, TEXT("%02u/%02u/%04u"), (UINT) tag->byAccountExpiresDay, + (UINT) tag->byAccountExpiresMonth, (UINT) 1900 + tag->byAccountExpiresYear); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Restrictions + LogWriteLog(1, Lids(IDS_L_110)); + // user can change password + if ((tag->byRestrictions & 0x01)) + LogWriteLog(2, Lids(IDS_L_111)); + else + LogWriteLog(2, Lids(IDS_L_112)); + + // unique password required + if ((tag->byRestrictions & 0x02)) + LogWriteLog(2, Lids(IDS_L_113), Lids(IDS_YES)); + else + LogWriteLog(2, Lids(IDS_L_113), Lids(IDS_NO)); + + // Password interval + LogWriteLog(1, Lids(IDS_L_114)); + if (tag->wPasswordInterval == 0) + LogWriteLog(0, Lids(IDS_L_107)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->wPasswordInterval); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Grace Logins + LogWriteLog(1, Lids(IDS_L_115)); + if (tag->byGraceLoginReset == 0xff) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->byGraceLoginReset); + + LogWriteLog(0, Lids(IDS_CRLF)); + + LogWriteLog(1, Lids(IDS_L_116), (UINT) tag->byMinPasswordLength); + + // Max Connections + LogWriteLog(1, Lids(IDS_L_117)); + if (tag->wMaxConnections == 0) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->wMaxConnections); + + LogWriteLog(0, Lids(IDS_CRLF)); + + LogWriteLog(1, Lids(IDS_L_118), (ULONG) tag->lBalance); + LogWriteLog(1, Lids(IDS_L_119), (ULONG) tag->lCreditLimit); + + // Max Disk blocks + LogWriteLog(1, Lids(IDS_L_120)); + if (tag->lMaxDiskBlocks == 0x7FFFFFFF) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%lu"), (ULONG) tag->lMaxDiskBlocks); + + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_CRLF)); + +} // NWUserDefaultsLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUserInfoLog( + LPTSTR szUserName, + VOID *UInfo + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + struct tagLoginControl *tag; + LPTSTR FullName; + + tag = (struct tagLoginControl *) UInfo; + + LogWriteLog(1, Lids(IDS_L_105)); + + // Full Name + LogWriteLog(2, Lids(IDS_L_106)); + + FullName = NWUserNameGet(szUserName); + if (FullName != NULL) + LogWriteLog(2, FullName); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Account disabled + if (tag->byAccountDisabled == 0xff) + LogWriteLog(2, Lids(IDS_L_121), Lids(IDS_YES)); + else if ((tag->wBadLogins == 0xffff) && + (tag->lNextResetTime > (LONG)CachedServerTime)) + LogWriteLog(2, Lids(IDS_L_121), Lids(IDS_LOCKED_OUT)); + else + LogWriteLog(2, Lids(IDS_L_121), Lids(IDS_NO)); + + // Account expires + LogWriteLog(2, Lids(IDS_L_109)); + if (tag->byAccountExpires[0] == 0) + LogWriteLog(0, Lids(IDS_L_107)); + else + LogWriteLog(0, TEXT("%02u/%02u/%04u"), (UINT) tag->byAccountExpires[1], + (UINT) tag->byAccountExpires[2], (UINT) 1900 + tag->byAccountExpires[0]); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Password Expires + LogWriteLog(2, Lids(IDS_L_122)); + if (tag->byPasswordExpires[0] == 0) + LogWriteLog(0, Lids(IDS_L_107)); + else + LogWriteLog(0, TEXT("%02u/%02u/19%02u"), (int) tag->byPasswordExpires[1], + (int) tag->byPasswordExpires[2], (int) tag->byPasswordExpires[0]); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Grace logins + LogWriteLog(2, Lids(IDS_L_123)); + if (tag->byGraceLogins == 0xff) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->byGraceLogins); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // initial grace logins + LogWriteLog(2, Lids(IDS_L_115)); + if (tag->byGraceLoginReset == 0xff) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->byGraceLoginReset); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Min password length + LogWriteLog(2, Lids(IDS_L_116), (UINT) tag->byMinPasswordLength); + + // Password expiration + LogWriteLog(2, Lids(IDS_L_114)); + if (tag->wPasswordInterval == 0) + LogWriteLog(0, Lids(IDS_L_107)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->wPasswordInterval); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Max connections + LogWriteLog(2, Lids(IDS_L_117)); + if (tag->wMaxConnections == 0) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%u"), (UINT) tag->wMaxConnections); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Restrictions + // user can change password + LogWriteLog(2, Lids(IDS_L_110)); + if ((tag->byRestrictions & 0x01)) + LogWriteLog(3, Lids(IDS_L_111)); + else + LogWriteLog(3, Lids(IDS_L_112)); + + // unique password required + if ((tag->byRestrictions & 0x02)) + LogWriteLog(3, Lids(IDS_L_113), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_113), Lids(IDS_NO)); + + LogWriteLog(2, Lids(IDS_L_124), (UINT) tag->wBadLogins); + + // Max Disk Blocks + LogWriteLog(2, Lids(IDS_L_120)); + if (tag->lMaxDiskBlocks == 0x7FFFFFFF) + LogWriteLog(0, Lids(IDS_L_108)); + else + LogWriteLog(0, TEXT("%lX"), tag->lMaxDiskBlocks); + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Login Times + NWLoginTimesLog(tag->byLoginTimes); + +} // NWUserInfoLog + + +///////////////////////////////////////////////////////////////////////// +VOID +NWUserInfoGet( + LPTSTR szUserName, + VOID **UInfo + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static struct tagLoginControl xUI; + struct tagLoginControl *UserInfo = NULL; + char szAnsiUserName[MAX_USER_NAME_LEN]; + NWCCODE ret; + BYTE bySegment[128]; + BYTE byMoreSegments, byPropertyFlags; + + CharToOem(szUserName, szAnsiUserName); + ret = NWReadPropertyValue(CachedConn, szAnsiUserName, OT_USER, LOGIN_CONTROL, 1, bySegment, &byMoreSegments, &byPropertyFlags); + + if (ret == SUCCESSFUL) { + UserInfo = &xUI; + memset(UserInfo, 0, sizeof(struct tagLoginControl)); + memcpy(UserInfo, bySegment, sizeof (struct tagLoginControl)); + + // Now put the data in 'normal' Intel format + SWAPBYTES(UserInfo->wPasswordInterval); + SWAPBYTES(UserInfo->wMaxConnections); + SWAPWORDS(UserInfo->lMaxDiskBlocks); + SWAPBYTES(UserInfo->wBadLogins); + SWAPWORDS(UserInfo->lNextResetTime); + } + + *UInfo = (void *) UserInfo; + +} // NWUserInfoGet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWServerEnum( + LPTSTR Container, + SERVER_BROWSE_LIST **lpServList + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + int NumBufs = 0; + DWORD TotalEntries = 0; + ENUM_REC *BufHead, *CurrBuf, *OldBuf; + SERVER_BROWSE_LIST *ServList = NULL; + SERVER_BROWSE_BUFFER *SList = NULL; + DWORD status = 0; + DWORD i, j; + NETRESOURCE ResourceBuf; + + // Container is ignored - NW is a flat network topology... + SetProvider(NW_PROVIDER, &ResourceBuf); + + BufHead = CurrBuf = OldBuf = NULL; + status = EnumBufferBuild(&BufHead, &NumBufs, ResourceBuf); + + if (!status) { + // We have 0 to xxx Enum recs each with a buffer sitting off of it. Now + // need to consolidate these into one global enum list... + if (NumBufs) { + CurrBuf = BufHead; + + // Figure out how many total entries there are + while (CurrBuf) { + TotalEntries += CurrBuf->cEntries; + CurrBuf = CurrBuf->next; + } + + CurrBuf = BufHead; + + // Now create a Server List to hold all of these. + ServList = AllocMemory(sizeof(SERVER_BROWSE_LIST) + TotalEntries * sizeof(SERVER_BROWSE_BUFFER)); + + if (ServList == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + ServList->Count = TotalEntries; + SList = (SERVER_BROWSE_BUFFER *) &ServList->SList; + + j = 0; + + // Now loop through copying the data... + while (CurrBuf) { + for(i = 0; i < CurrBuf->cEntries; i++) { + if (CurrBuf->lpnr[i].lpRemoteName != NULL) + if (CurrBuf->lpnr[i].lpRemoteName[0] == TEXT('\\') && CurrBuf->lpnr[i].lpRemoteName[1] == TEXT('\\')) + lstrcpy(SList[j].Name, &CurrBuf->lpnr[i].lpRemoteName[2]); + else + lstrcpy(SList[j].Name, CurrBuf->lpnr[i].lpRemoteName); + else + lstrcpy(SList[j].Name, TEXT("")); + + if (CurrBuf->lpnr[i].lpComment != NULL) + lstrcpy(SList[j].Description, CurrBuf->lpnr[i].lpComment); + else + lstrcpy(SList[j].Description, TEXT("")); + + SList[j].Container = FALSE; + j++; + } + + OldBuf = CurrBuf; + CurrBuf = CurrBuf->next; + + // Free the old buffer + FreeMemory((HGLOBAL) OldBuf); + + } // while + + } // else (ServList) + + } // if (numbufs) + + } + + *lpServList = ServList; + return status; + +} // NWServerEnum + + +///////////////////////////////////////////////////////////////////////// +ULONG +NWShareSizeGet( + LPTSTR Share + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR RootPath[MAX_PATH + 1]; + DWORD sectorsPC, bytesPS, FreeClusters, Clusters; + DWORD TotalSpace, FreeSpace; + + TotalSpace = FreeSpace = 0; + + wsprintf(RootPath, TEXT("\\\\%s\\%s\\"), CachedServer, Share); + if (GetDiskFreeSpace(RootPath, §orsPC, &bytesPS, &FreeClusters, &Clusters)) { + TotalSpace = Clusters * sectorsPC * bytesPS; + FreeSpace = FreeClusters * sectorsPC * bytesPS; + } + + // total - free = approx allocated space (if multiple shares on drive then + // this doesn't take that into account, we just want an approximation... + return TotalSpace - FreeSpace; + +} // NWShareSizeGet + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWSharesEnum( + SHARE_LIST **lpShares + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + int NumBufs = 0; + DWORD TotalEntries = 0; + ENUM_REC *BufHead, *CurrBuf, *OldBuf; + SHARE_LIST *ShareList = NULL; + SHARE_BUFFER *SList = NULL; + DWORD status; + DWORD i, j; + NETRESOURCE ResourceBuf; + + // Setup NETRESOURCE data structure + SetProvider(NW_PROVIDER, &ResourceBuf); + + ResourceBuf.lpRemoteName = CachedServer; + ResourceBuf.dwUsage = RESOURCEUSAGE_CONTAINER; + + status = EnumBufferBuild(&BufHead, &NumBufs, ResourceBuf); + + if (!status) { + // We have 0 to xxx Enum recs each with a buffer sitting off of it. Now + // need to consolidate these into one global enum list... + if (NumBufs) { + CurrBuf = BufHead; + + // Figure out how many total entries there are + while (CurrBuf) { + TotalEntries += CurrBuf->cEntries; + CurrBuf = CurrBuf->next; + } + + CurrBuf = BufHead; + + // Now create a Server List to hold all of these. + ShareList = (SHARE_LIST *) AllocMemory(sizeof(SHARE_LIST) + (TotalEntries * sizeof(SHARE_BUFFER))); + + if (ShareList == NULL) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + j = 0; + + // Zero out everything and get pointer to list + memset(ShareList, 0, sizeof(SHARE_LIST) + (TotalEntries * sizeof(SHARE_BUFFER))); + ShareList->Count = TotalEntries; + SList = (SHARE_BUFFER *) &ShareList->SList; + + // Now loop through copying the data... + while (CurrBuf) { + for(i = 0; i < CurrBuf->cEntries; i++) { + if (CurrBuf->lpnr[i].lpRemoteName != NULL) + lstrcpy(SList[j].Name, ShareNameParse(CurrBuf->lpnr[i].lpRemoteName)); + else + lstrcpy(SList[j].Name, TEXT("")); + + SList[j].Size = NWShareSizeGet(SList[j].Name); + SList[j].Index = (USHORT) j; + j++; + } + + OldBuf = CurrBuf; + CurrBuf = CurrBuf->next; + + // Free the old buffer + FreeMemory((HGLOBAL) OldBuf); + + } // while + + } // else (ShareList) + + } // if (numbufs) + + } + + *lpShares = ShareList; + return status; + +} // NWSharesEnum + + +///////////////////////////////////////////////////////////////////////// +VOID +NWServerInfoReset( + SOURCE_SERVER_BUFFER *SServ + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static VERSION_INFO NWInfo; + NWCCODE ret = 0; + + ret = NWGetFileServerVersionInfo(CachedConn, &NWInfo); + + // BUGBUG: This API returns fail (8801) - but is actually succeding, + // just ignore error for right now as it really doesn't matter for the + // version info. +// if (ret == SUCCESSFUL) { + SServ->VerMaj = NWInfo.Version; + SServ->VerMin = NWInfo.SubVersion; +// } + +} // NWServerInfoReset + + +///////////////////////////////////////////////////////////////////////// +VOID +NWServerInfoSet( + LPTSTR ServerName, + SOURCE_SERVER_BUFFER *SServ + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static VERSION_INFO NWInfo; + NWCCODE ret = 0; + + CursorHourGlass(); + lstrcpy(SServ->Name, ServerName); + NWServerInfoReset(SServ); + + // Fill in share list + NWSharesEnum(&SServ->ShareList); + +#ifdef DEBUG +{ + DWORD i; + + dprintf(TEXT("Adding NW Server: %s\n"), SServ->Name); + dprintf(TEXT(" Version: %u.%u\n"), (UINT) SServ->VerMaj, (UINT) SServ->VerMin); + dprintf(TEXT(" Shares\n")); + dprintf(TEXT(" +---------------------------------------+\n")); + if (SServ->ShareList) { + for (i = 0; i < SServ->ShareList->Count; i++) { + dprintf(TEXT(" %-15s AllocSpace %lu\n"), SServ->ShareList->SList[i].Name, SServ->ShareList->SList[i].Size); + } + } + else + dprintf(TEXT(" \n")); + + dprintf(TEXT("\n")); + +} +#endif + + CursorNormal(); + +} // NWServerInfoSet + + +///////////////////////////////////////////////////////////////////////// +BOOL +NWServerValidate( + HWND hWnd, + LPTSTR ServerName, + BOOL DupFlag + ) + +/*++ + +Routine Description: + + Validates a given server - makes sure it can be connected to and + that the user has admin privs on it. + +Arguments: + + +Return Value: + + +--*/ + +{ + DWORD Status; + BOOL ret = FALSE; + SOURCE_SERVER_BUFFER *SServ = NULL; + DWORD dwObjectID = 0; + DWORD Size; + BYTE AccessLevel; + TCHAR UserName[MAX_USER_NAME_LEN + 1]; + static TCHAR LocServer[MAX_SERVER_NAME_LEN+3]; + LPVOID lpMessageBuffer; + + CursorHourGlass(); + + if (DupFlag) + SServ = SServListFind(ServerName); + + if (SServ == NULL) { + // Get Current Logged On User + lstrcpy(UserName, TEXT("")); + Size = sizeof(UserName); + WNetGetUser(NULL, UserName, &Size); + + lstrcpy(LocServer, TEXT("\\\\")); + lstrcat(LocServer, ServerName); + + if (UseAddPswd(hWnd, UserName, LocServer, Lids(IDS_S_6), NW_PROVIDER)) { + + Status = NWServerSet(ServerName); + + if (Status) { + + if (GetLastError() != 0) + WarningError(Lids(IDS_NWCANT_CON), ServerName); + + } else { + if (IsNCPServerFPNW(CachedConn)) + WarningError(Lids(IDS_E_18), ServerName); + else { + Status = NWCGetBinderyAccessLevel(CachedConn, &AccessLevel, &dwObjectID); + + if (!Status) { + AccessLevel &= BS_SUPER_READ; + if (AccessLevel == BS_SUPER_READ) + ret = TRUE; + else + WarningError(Lids(IDS_NWNO_ADMIN), ServerName); + } + } + } + } else { + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), 0, + (LPTSTR) &lpMessageBuffer, 0, NULL ); + + if (GetLastError() != 0) + WarningError(Lids(IDS_E_9), ServerName, lpMessageBuffer); + + LocalFree(lpMessageBuffer); + } + } else { + // Already in source server list - can't appear more then once + WarningError(Lids(IDS_E_14), ServerName); + } + + CursorNormal(); + return ret; + +} // NWServerValidate + + +///////////////////////////////////////////////////////////////////////// +LPTSTR +NWRightsLog( + DWORD Rights + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + static TCHAR NWRights[15]; + + lstrcpy(NWRights, Lids(IDS_S_34)); + + // Read + if (!(Rights & 0x01)) + NWRights[2] = TEXT(' '); + + // Write + if (!(Rights & 0x02)) + NWRights[3] = TEXT(' '); + + // Create + if (!(Rights & 0x08)) + NWRights[4] = TEXT(' '); + + // Delete (Erase) + if (!(Rights & 0x10)) + NWRights[5] = TEXT(' '); + + // Parental + if (!(Rights & 0x20)) + NWRights[8] = TEXT(' '); + + // Search + if (!(Rights & 0x40)) + NWRights[7] = TEXT(' '); + + // Modify + if (!(Rights & 0x80)) + NWRights[6] = TEXT(' '); + + // Supervisor (all rights set) + if ((Rights & 0xFB) != 0xFB) + NWRights[1] = TEXT(' '); + + return NWRights; + +} // NWRightsLog + + +///////////////////////////////////////////////////////////////////////// +NTSTATUS +MapNwRightsToNTAccess( + ULONG NWRights, + PRIGHTS_MAPPING pMap, + ACCESS_MASK *pAccessMask + ) + +/*++ + +Routine Description: + + Map a NW Right to the appropriate NT AccessMask + +Arguments: + + NWRights - Netware rights we wish to map + pMap - pointer to structure that defines the mapping + +Return Value: + + The NT AccessMask corresponding to the NW Rights + +--*/ + +{ + PNW_TO_NT_MAPPING pNWToNtMap = pMap->Nw2NtMapping ; + ACCESS_MASK AccessMask = 0 ; + + if (!pAccessMask) + return STATUS_INVALID_PARAMETER ; + + *pAccessMask = 0x0 ; + + // go thru the mapping structuring, OR-ing in bits along the way + while (pNWToNtMap->NWRight) { + + if (pNWToNtMap->NWRight & NWRights) + AccessMask |= pNWToNtMap->NTAccess ; + + pNWToNtMap++ ; + } + + *pAccessMask = AccessMask ; + + return STATUS_SUCCESS ; +} // MapNwRightsToNTAccess + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWPrintServersEnum( + PRINT_SERVER_LIST **PS + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + PRINT_SERVER_LIST *psl; + PRINT_SERVER_BUFFER *pbuff; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD status = 0; + char szAnsiPrinterName[MAX_USER_NAME_LEN + 1]; + TCHAR szPrinterName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + DWORD dwObjectID = 0xFFFFFFFFL; + BYTE byPropertiesFlag = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + NWCCODE ret; + + psl = (PRINT_SERVER_LIST *) AllocMemory(sizeof(PRINT_SERVER_LIST) + (NumRecs * sizeof(PRINT_SERVER_BUFFER))); + + if (!psl) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + pbuff = psl->PSList; + + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiPrinterName, ""); + + // Loop through bindery getting all the users. + while ((ret = NWScanObject(CachedConn, "*", OT_PRINT_SERVER, &dwObjectID, szAnsiPrinterName, + &wFoundUserType, &byPropertiesFlag, + &byObjectFlag, &byObjectSecurity)) == SUCCESSFUL) { + + // Got user - now convert and save off the information + OemToChar(szAnsiPrinterName, szPrinterName); + + lstrcpy(pbuff[Count].Name, szPrinterName); + Count++; + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + psl = (PRINT_SERVER_LIST *) ReallocMemory((HGLOBAL) psl, sizeof(PRINT_SERVER_LIST) + (NumRecs * sizeof(PRINT_SERVER_BUFFER))); + pbuff = psl->PSList; + + if (!psl) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + } + + } + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + psl = (PRINT_SERVER_LIST *) ReallocMemory((HGLOBAL) psl, sizeof(PRINT_SERVER_LIST) + (Count * sizeof(PRINT_SERVER_BUFFER))); + + if (!psl) + status = ERROR_NOT_ENOUGH_MEMORY; + } + + psl->Count = Count; + *PS = psl; + + return status; + +} // NWPrintServersEnum + + +///////////////////////////////////////////////////////////////////////// +DWORD +NWPrintOpsEnum( + USER_LIST **lpUsers + ) + +/*++ + +Routine Description: + + First need to enumerate all the print servers on the NetWare system + we are pointing to. Next loop through each of these print servers + and enumerate the print operators on each of them. + +Arguments: + + +Return Value: + + +--*/ + +{ + PRINT_SERVER_LIST *psl = NULL; + PRINT_SERVER_BUFFER *PSList; + ULONG pCount; + USER_LIST *Users = NULL; + USER_BUFFER *UserBuffer; + DWORD NumRecs = DEF_NUM_RECS; // Default 200 names + DWORD Count = 0; + DWORD ipsl = 0, iseg = 0; + DWORD status = 0; + char szAnsiUserName[MAX_USER_NAME_LEN + 1]; + char szAnsiName[MAX_GROUP_NAME_LEN + 1]; + TCHAR szUserName[MAX_USER_NAME_LEN + 1]; + WORD wFoundUserType = 0; + DWORD dwObjectID = 0xFFFFFFFFL; + BYTE byPropertyFlags = 0; + BYTE byObjectFlag = 0; + BYTE byObjectSecurity = 0; + UCHAR Segment = 1; + DWORD bySegment[32]; + BYTE byMoreSegments; + NWCCODE ret; + + *lpUsers = NULL; + + // Enumerate the print servers - if there are none, then there are no printer ops + NWPrintServersEnum(&psl); + if ((psl == NULL) || (psl->Count == 0)) { + if (psl != NULL) + FreeMemory(psl); + + return 0; + } + + // Got some servers - loop through them enumerating users + Users = (USER_LIST *) AllocMemory(sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + } else { + UserBuffer = Users->UserBuffer; + PSList = psl->PSList; + + for (pCount = 0; pCount < psl->Count; pCount++) { + // init to NULL so doesn't have garbage if call fails + lstrcpyA(szAnsiUserName, ""); + CharToOem(PSList[ipsl++].Name, szAnsiName); + + // Loop through bindery getting all the users. + do { + if (!(ret = NWReadPropertyValue(CachedConn, szAnsiName, OT_PRINT_SERVER, PS_OPERATORS, + Segment, (BYTE *) bySegment, &byMoreSegments, &byPropertyFlags))) { + + Segment++; + // loop through properties converting them to user names + iseg = 0; + while ((bySegment[iseg]) && (iseg < 32)) { + if (!(ret = NWGetObjectName(CachedConn, bySegment[iseg], szAnsiUserName, &wFoundUserType))) { + // Got user - now convert and save off the information + OemToChar(szAnsiUserName, szUserName); + + // Map out Supervisor (already print-op privs) + if (lstrcmpi(szUserName, Lids(IDS_S_28))) { + lstrcpy(UserBuffer[Count].Name, szUserName); + lstrcpy(UserBuffer[Count].NewName, szUserName); + Count++; + } + + // Check if we have to re-allocate buffer + if (Count >= NumRecs) { + NumRecs += DEF_NUM_RECS; + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * NumRecs)); + + if (!Users) { + status = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + UserBuffer = Users->UserBuffer; + } + } + iseg++; + } + + } else // if NWReadPropertyValue + byMoreSegments = 0; + + } while (byMoreSegments); + + // Gotta clear this out from the last loop + if (Count) + ret = 0; + } + } + + // check if error occured... + if (ret) + status = ret; + + // Now slim down the list to just what we need. + if (!status) { + Users = (USER_LIST *) ReallocMemory((HGLOBAL) Users, sizeof(USER_LIST) + (sizeof(USER_BUFFER) * Count)); + + if (!Users) + status = ERROR_NOT_ENOUGH_MEMORY; + else { + // Sort the server list before putting it in the dialog + UserBuffer = Users->UserBuffer; + qsort((void *) UserBuffer, (size_t) Count, sizeof(USER_BUFFER), UserListCompare); + } + } + + Users->Count = Count; + *lpUsers = Users; + + return status; + +} // NWPrintOpsEnum + + + +///////////////////////////////////////////////////////////////////////// + +VOID +NWServerTimeGet( + ) + +/*++ + +Routine Description: + + Queries server for it's current local time which is then converted to + elasped minutes since 1985 in order to compare with the lNextResetTime + field of the LOGIN_CONTROL structure (which must be byte-aligned). + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + DWORD dwYear = 0; + DWORD dwMonth = 0; + DWORD dwDay = 0; + DWORD dwHour = 0; + DWORD dwMinute = 0; + DWORD dwSecond = 0; + DWORD dwDayOfWeek = 0; + DWORD dwServerTime = 0; + + CachedServerTime = 0xffffffff; // re-initialize... + + if (!NWGetFileServerDateAndTime( + CachedConn, + (LPBYTE)&dwYear, + (LPBYTE)&dwMonth, + (LPBYTE)&dwDay, + (LPBYTE)&dwHour, + (LPBYTE)&dwMinute, + (LPBYTE)&dwSecond, + (LPBYTE)&dwDayOfWeek)) + { + if (NWTimeMap(dwDay, dwMonth, dwYear, 1985, &dwServerTime)) + { + dwServerTime += dwHour * 3600; + dwServerTime += dwMinute * 60; + dwServerTime += dwSecond; + + CachedServerTime = dwServerTime / 60; // convert to minutes... + } + } +} + +///////////////////////////////////////////////////////////////////////// + +BOOL +IsNCPServerFPNW( + NWCONN_HANDLE Conn + ) + +/*++ + +Routine Description: + + Check if this an FPNW server by checking for a specific object + type and property. + +Arguments: + + Conn - connection id of ncp server. + +Return Value: + + Returns true if ncp server is fpnw. + +--*/ + +{ + NWCCODE ret; + BYTE bySegment[128]; + BYTE byMoreSegments, byPropertyFlags; + + memset(bySegment, 0, sizeof(bySegment)); + + ret = NWReadPropertyValue( + CachedConn, + MS_EXTENDED_NCPS, + 0x3B06, + FPNW_PDC, + 1, + bySegment, + &byMoreSegments, + &byPropertyFlags + ); + + return (ret == SUCCESSFUL) && (BOOL)(BYTE)bySegment[0]; +} diff --git a/private/nw/convert/nwconv/nwnetapi.h b/private/nw/convert/nwconv/nwnetapi.h new file mode 100644 index 000000000..d9089a520 --- /dev/null +++ b/private/nw/convert/nwconv/nwnetapi.h @@ -0,0 +1,133 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HNWNETAPI_ +#define _HNWNETAPI_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef NTSTATUS +typedef LONG NTSTATUS; +#endif + +typedef struct _USER_RIGHTS_LIST { + TCHAR Name[MAX_USER_NAME_LEN]; + DWORD Rights; +} USER_RIGHTS_LIST; + +int NWGetMaxServerNameLen(); +int NWGetMaxUserNameLen(); + +BOOL NWObjectNameGet( DWORD ObjectID, LPTSTR ObjectName ); + +VOID NWUserInfoGet(LPTSTR szUserName, VOID **UInfo); +VOID NWUserInfoLog(LPTSTR szUserName, VOID *UInfo); +DWORD NWServerSet(LPTSTR FileServer); +DWORD NWServerFree(); + +DWORD NWUsersEnum(USER_LIST **lpUsers, BOOL Display); +DWORD NWGroupsEnum(GROUP_LIST **lpGroups, BOOL Display); +DWORD NWGroupUsersEnum(LPTSTR GroupName, USER_LIST **lpUsers); +DWORD NWUserEquivalenceEnum(LPTSTR UserName, USER_LIST **lpUsers); +DWORD NWServerEnum(LPTSTR Container, SERVER_BROWSE_LIST **lpServList); +DWORD NWSharesEnum(SHARE_LIST **lpShares); + +VOID NWUserDefaultsGet(VOID **UDefaults); +VOID NWUserDefaultsMap(VOID *NWUDefaults, NT_DEFAULTS *NTDefaults); +VOID NWUserDefaultsLog(VOID *UDefaults); +VOID NWNetUserMapInfo (LPTSTR szUserName, VOID *UInfo, NT_USER_INFO *NT_UInfo ); +VOID NWFPNWMapInfo(VOID *NWUInfo, PFPNW_INFO fpnw); + +VOID NWUseDel(LPTSTR ServerName); +BOOL NWIsAdmin(LPTSTR UserName); +VOID NWServerInfoReset(SOURCE_SERVER_BUFFER *SServ); +VOID NWServerInfoSet(LPTSTR ServerName, SOURCE_SERVER_BUFFER *SServ); +BOOL NWServerValidate(HWND hWnd, LPTSTR ServerName, BOOL DupFlag); +DWORD NWFileRightsEnum(LPTSTR FileName, USER_RIGHTS_LIST **lpUsers, DWORD *UserCount, BOOL DownLevel); +LPTSTR NWRightsLog(DWORD Rights); +LPTSTR NWSpecialNamesMap(LPTSTR Name); + +VOID NWServerTimeGet(); + +typedef struct _NW_TO_NT_MAPPING { + ULONG NWRight ; + ULONG NTAccess ; +} NW_TO_NT_MAPPING, *PNW_TO_NT_MAPPING ; + + +// +// structure used to define how the Rights for a Netware object maps +// to the corresponding NT AccessMasks. +// +// first entry is the AceFlags to distinguish between ACE for the Object +// and ACE for inheritted objects +// +// the GENERIC_MAPPING structure should match that already defined for +// the NT object in question. +// +// the array of NW mappings defines the NT Access Mask for each NW Right +// the object uses. the last entry should be {0, 0}. +// +// for example, file object mappings: +// +// RIGHTS_MAPPING FileRightsMapping = +// { +// 0, +// { FILE_GENERIC_READ, +// FILE_GENERIC_WRITE, +// FILE_GENERIC_EXECUTE, +// FILE_ALL_ACCESS +// }, +// { { NW_FILE_READ, GENERIC_READ } +// { NW_FILE_WRITE, GENERIC_WRITE } +// { NW_FILE_CREATE, 0 } +// { NW_FILE_DELETE, GENERIC_WRITE } +// { NW_FILE_PERM, WRITE_DAC } +// { NW_FILE_SCAN, 0 } +// { NW_FILE_MODIFY, GENERIC_WRITE } +// { NW_FILE_SUPERVISOR, GENERIC_ALL } +// { 0, 0 } +// } +// } ; +// +// + +typedef struct _RIGHTS_MAPPING { + ULONG NtAceFlags ; + GENERIC_MAPPING GenericMapping ; + NW_TO_NT_MAPPING Nw2NtMapping[] ; +} RIGHTS_MAPPING, *PRIGHTS_MAPPING ; + + +// predefined mappings (defined in nwnetapi.c) +extern RIGHTS_MAPPING FileRightsMapping ; +extern RIGHTS_MAPPING DirRightsMapping ; +extern RIGHTS_MAPPING PrintRightsMapping ; +extern RIGHTS_MAPPING JobRightsMapping ; + +// define the NW_FILE_* rights +#define NW_FILE_READ 0x0001 +#define NW_FILE_WRITE 0x0002 +#define NW_FILE_CREATE 0x0008 +#define NW_FILE_DELETE 0x0010 +#define NW_FILE_PERM 0x0020 +#define NW_FILE_SCAN 0x0040 +#define NW_FILE_MODIFY 0x0080 +#define NW_FILE_SUPERVISOR 0x0100 + +#define NW_PRINT_USER 0x0001 +#define NW_PRINT_ADMIN 0x0002 +#define NW_PRINTJOB_ADMIN 0x0004 + +NTSTATUS MapNwRightsToNTAccess( ULONG NWRights, PRIGHTS_MAPPING pMap, ACCESS_MASK *pAccessMask ) ; +DWORD NWPrintOpsEnum(USER_LIST **lpUsers); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/private/nw/convert/nwconv/nwrights.h b/private/nw/convert/nwconv/nwrights.h new file mode 100644 index 000000000..ff78cb9e8 --- /dev/null +++ b/private/nw/convert/nwconv/nwrights.h @@ -0,0 +1,168 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + + +Module Name: + + nwrights.h + +Abstract: + + This module contains the prototypes for the + routines called to manipulate security descriptors. + +Author: + + Chuck Y. Chan (chuckc) + +Revision History: + + ChuckC 24th Oct 1993 Created + +--*/ + + +// +// structure used to define how a single NW Right maps to +// an NT Access mask. +// + +typedef struct _NW_TO_NT_MAPPING { + ULONG NWRight ; + ULONG NTAccess ; +} NW_TO_NT_MAPPING, *PNW_TO_NT_MAPPING ; + + +// +// structure used to define how the Rights for a Netware object maps +// to the corresponding NT AccessMasks. +// +// first entry is the AceFlags to distinguish between ACE for the Object +// and ACE for inheritted objects +// +// the GENERIC_MAPPING structure should match that already defined for +// the NT object in question. +// +// the array of NW mappings defines the NT Access Mask for each NW Right +// the object uses. the last entry should be {0, 0}. +// +// for example, file object mappings: +// +// RIGHTS_MAPPING FileRightsMapping = +// { +// 0, +// { FILE_GENERIC_READ, +// FILE_GENERIC_WRITE, +// FILE_GENERIC_EXECUTE, +// FILE_ALL_ACCESS +// }, +// { { NW_FILE_READ, GENERIC_READ } +// { NW_FILE_WRITE, GENERIC_WRITE } +// { NW_FILE_CREATE, 0 } +// { NW_FILE_DELETE, GENERIC_WRITE } +// { NW_FILE_PERM, WRITE_DAC } +// { NW_FILE_SCAN, 0 } +// { NW_FILE_MODIFY, GENERIC_WRITE } +// { NW_FILE_SUPERVISOR, GENERIC_ALL } +// { 0, 0 } +// } +// } ; +// +// + +typedef struct _RIGHTS_MAPPING { + ULONG NtAceFlags ; + GENERIC_MAPPING GenericMapping ; + NW_TO_NT_MAPPING Nw2NtMapping[] ; +} RIGHTS_MAPPING, *PRIGHTS_MAPPING ; + +// +// define the NW_FILE_* rights +// + +#define NW_FILE_READ 0x0001 +#define NW_FILE_WRITE 0x0002 +#define NW_FILE_CREATE 0x0008 +#define NW_FILE_DELETE 0x0010 +#define NW_FILE_PERM 0x0020 +#define NW_FILE_SCAN 0x0040 +#define NW_FILE_MODIFY 0x0080 +#define NW_FILE_SUPERVISOR 0x0100 + +#define NW_PRINT_USER 0x0001 +#define NW_PRINT_ADMIN 0x0002 +#define NW_PRINTJOB_ADMIN 0x0004 + +// +// #define these so they can be changed easily. these macros +// should be used to free the memory allocated by the routines in +// this module. +// + +#define NW_ALLOC(x) ((LPBYTE)LocalAlloc(LPTR,x)) +#define NW_FREE(p) ((void)LocalFree((HLOCAL)p)) + +// +// predefined mappings (defined in nwrights.c) +// + +extern RIGHTS_MAPPING FileRightsMapping ; +extern RIGHTS_MAPPING DirRightsMapping ; +extern RIGHTS_MAPPING PrintRightsMapping ; +extern RIGHTS_MAPPING JobRightsMapping ; + +// +// function prototypes. details of parameters can be found in nwrights.c +// + +NTSTATUS +NwAddRight( + PSECURITY_DESCRIPTOR pSD, + PSID pSid, + ULONG Rights, + PRIGHTS_MAPPING pMap, + PSECURITY_DESCRIPTOR *ppNewSD + ) ; + +NTSTATUS +NwRemoveRight( + PSECURITY_DESCRIPTOR pSD, + PSID pSid, + ULONG Rights, + PRIGHTS_MAPPING pMap + ) ; + +NTSTATUS +NwCheckTrusteeRights( + PSECURITY_DESCRIPTOR pSD, + PSID pSid, + ULONG Rights, + PRIGHTS_MAPPING pMap + ) ; + +NTSTATUS +NwScanTrustees( + PSECURITY_DESCRIPTOR pSD, + PSID **pppSids, + ULONG **ppRights, + ULONG *pCount, + BOOL fAccessRightsOnly, + PRIGHTS_MAPPING pMapObject, + PRIGHTS_MAPPING pMapNewObject + ) ; + +NTSTATUS MapNwRightsToNTAccess( + ULONG NWRights, + PRIGHTS_MAPPING pMap, + ACCESS_MASK *pAccessMask + ) ; + +NTSTATUS MapSpecificToGeneric( + ACCESS_MASK * pAccessMask, + PGENERIC_MAPPING pGenMapping ) ; + +NTSTATUS CreateNewSecurityDescriptor( + PSECURITY_DESCRIPTOR *ppNewSD, + PSECURITY_DESCRIPTOR pSD, + PACL pAcl) ; diff --git a/private/nw/convert/nwconv/resource.h b/private/nw/convert/nwconv/resource.h new file mode 100644 index 000000000..8c0ef69e1 --- /dev/null +++ b/private/nw/convert/nwconv/resource.h @@ -0,0 +1,245 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HRESOURCE_ +#define _HRESOURCE_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "helpid.h" + +// +------------------------------------------------------------------------+ +// | Main MoveIt Dialog +// +------------------------------------------------------------------------+ + +#define IDR_MAINFRAME 1 +#define IDD_ABOUTBOX 999 + +#define ID_FILE_OPEN 1000 +#define ID_HELP_CONT 1001 +#define ID_HELP_INDEX 1002 +#define ID_HELP_USING 1003 +#define ID_APP_ABOUT 1004 +#define ID_FILE_SAVE 1005 +#define ID_LOGGING 1006 +#define ID_FILE_DEFAULT 1007 +#define IDC_EXIT 1008 + +#define IDC_EDIT1 1010 +#define IDC_LIST1 1011 +#define IDC_TRIAL 1012 +#define IDC_USERINF 1013 +#define IDC_ADD 1014 +#define IDC_DELETE 1015 +#define IDC_FILEINF 1016 + +#ifndef IDHELP +#define IDHELP 1017 +#endif // IDHELP + +// Common Advanced>> button +#define IDC_ADVANCED 1018 +#define ID_INIT 1019 + +// +------------------------------------------------------------------------+ +// | Get Servers Dialog +// +------------------------------------------------------------------------+ +#define IDC_EDITNWSERV 1020 +#define IDC_EDITNTSERV 1021 +#define IDC_NWBROWSE 1022 +#define IDC_NTBROWSE 1023 +#define ID_SETSEL 1024 + +// +------------------------------------------------------------------------+ +// | User Dialog +// +------------------------------------------------------------------------+ +#define IDC_CHKUSERS 1030 +#define IDC_TABUSERS 1031 + +#define IDC_PWCONST 1032 + +#define IDC_CHKPWFORCE 1033 +#define IDC_USERCONST 1034 +#define IDC_GROUPCONST 1035 + +#define IDC_CHKSUPER 1036 +#define IDC_CHKADMIN 1037 +#define IDC_CHKNETWARE 1038 +#define IDC_CHKMAPPING 1039 +#define IDC_MAPPINGFILE 1040 +#define IDC_BTNMAPPINGFILE 1041 +#define IDC_BTNMAPPINGEDIT 1042 +#define IDC_CHKFPNW 1043 + +// These must be contiguous... +#define IDC_RADIO1 1045 +#define IDC_RADIO2 1046 +#define IDC_RADIO3 1047 +#define IDC_RADIO4 1048 +#define IDC_RADIO5 1049 +#define IDC_RADIO6 1050 +#define IDC_RADIO7 1051 +#define IDC_RADIO8 1052 +#define IDC_RADIO9 1053 +#define IDC_RADIO10 1054 + +#define IDC_TRUSTED 1055 +#define IDC_CHKTRUSTED 1056 +#define IDC_BTNTRUSTED 1057 + +#define IDC_STATDUP 1058 + +#define IDC_DEFAULTBOX 1059 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ + +#define IDC_DOMAIN 1060 +#define IDC_LOADNWSERV 1061 +#define IDC_LOADNTSERV 1062 +#define IDC_LOADDOMAIN 1063 +#define IDC_ALTOK 1064 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_CHKUVERBOSE 1070 +#define IDC_CHKFVERBOSE 1071 +#define IDC_CHKERROR 1072 +#define IDC_VIEWLOG 1073 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ + +#define IDC_S_CUR_CONV 1100 +#define IDC_S_TOT_CONV 1101 +#define IDC_S_SRCSERV 1102 +#define IDC_S_DESTSERV 1103 +#define IDC_S_CONVTXT 1104 +#define IDC_S_CUR_NUM 1105 +#define IDC_S_CUR_TOT 1106 +#define IDC_S_ITEMLABEL 1107 +#define IDC_S_STATUSITEM 1108 +#define IDC_S_TOT_COMP 1109 +#define IDC_S_TOT_GROUPS 1110 +#define IDC_S_TOT_USERS 1111 +#define IDC_S_TOT_FILES 1112 +#define IDC_S_TOT_ERRORS 1113 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_PANEL1 1130 +#define IDC_PANEL2 1131 +#define IDC_PANEL3 1132 +#define IDC_PANEL4 1133 +#define IDC_PANEL5 1134 + +#define IDC_PANEL6 1135 +#define IDC_PANEL7 1136 +#define IDC_PANEL8 1137 +#define IDC_PANEL9 1138 +#define IDC_PANEL10 1139 + +#define IDR_LISTICONS 1200 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ + +#define IDC_CHKFILES 1301 +#define IDC_MODIFY 1302 +#define IDC_FILES 1303 +#define IDC_FOPTIONS 1304 +#define IDC_TABFILES 1305 +#define IDC_LIST2 1306 + +#define IDC_COMBO1 1307 +#define IDC_COMBO2 1308 +#define IDC_NEWSHARE 1309 +#define IDC_PROPERTIES 1310 + +#define ID_UPDATELIST 1311 +#define IDC_VOLUME 1312 +#define IDC_FSERVER 1313 +#define IDC_TSERVER 1314 + +#define IDR_FILEICONS 1320 +#define IDR_CHECKICONS 1321 +#define ID_CHECKCHECK 1322 + +// Menus for the dialog +#define IDM_EXP_ONE 1330 +#define IDM_EXP_BRANCH 1331 +#define IDM_EXP_ALL 1332 +#define IDM_COLLAPSE 1333 + +#define IDM_VIEW_BOTH 1334 +#define IDM_VIEW_TREE 1335 +#define IDM_VIEW_DIR 1336 + +#define IDM_HIDDEN 1337 +#define IDM_SYSTEM 1338 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_PASSWORD 1340 +#define IDC_SERVNAME 1341 +#define IDC_USERNAME 1342 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_SHARENAME 1350 +#define IDC_EDIT2 1352 +#define IDC_EDIT3 1353 +#define ID_UPDATECOMBO 1354 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_OLDNAME 1360 +#define IDC_NEWNAME 1361 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_LIST3 1370 +#define IDC_T_DRIVES 1371 +#define IDC_T_SHARES 1372 +#define IDC_T_VOLUMES 1373 +#define IDC_VERSION 1374 +#define IDC_TYPE 1375 + +#define ID_REDRAWLIST 1380 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_USERS 1390 +#define IDC_GROUPS 1391 + +// +------------------------------------------------------------------------+ +// +------------------------------------------------------------------------+ +#define IDC_DLGMAIN 1999 +#define IDC_STATIC -1 + +#define IDH_H 3000 + +// +------------------------------------------------------------------------+ +// | About Box +// +------------------------------------------------------------------------+ +#define IDC_AVAIL_MEM 101 +#define IDC_PHYSICAL_MEM 101 +#define IDC_LICENSEE_COMPANY 104 +#define IDC_LICENSEE_NAME 105 +#define IDD_SPLASH 105 +#define IDC_MATH_COPR 106 +#define IDC_DISK_SPACE 107 +#define IDC_BIGICON 1001 + + +#define IDM_ADDSEL 2000 +#define IDC_SIZEHORZ 500 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/sbrowse.c b/private/nw/convert/nwconv/sbrowse.c new file mode 100644 index 000000000..9ee80657c --- /dev/null +++ b/private/nw/convert/nwconv/sbrowse.c @@ -0,0 +1,1153 @@ +/* + +-------------------------------------------------------------------------+ + | Server Browsing Dialog Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [sbrowse.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Dec 01, 1993] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Jun 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "globals.h" + +#include + +#include "nwconv.h" +#include "hierdraw.h" +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" + +#define SERVER_TYPE_NT 0 +#define SERVER_TYPE_NW 1 + +extern BOOL IsNetWareBrowse; +static int BrowseType; + + +TCHAR NetProvider[30]; + + +// Internal defines +VOID DlgServSel_OnDrawItem(HWND hwnd, DRAWITEMSTRUCT FAR* lpDrawItem); +BOOL DlgServSel_OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam); +VOID DlgServSel_ActionItem(HWND hWndList, DWORD dwData, WORD wItemNum); +LRESULT CALLBACK DlgServSel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +BOOL EnumServs(HWND hDlg); + + +#define ROWS 2 +#define COLS 3 + +HEIRDRAWSTRUCT HierDrawStruct; + +static HWND hEdit; +static HWND hParent; +static SERVER_BROWSE_LIST *ServList = NULL; +static TCHAR SourceServer[256]; +static TCHAR DestServer[256]; +static DEST_SERVER_BUFFER *DServ = NULL; +static SOURCE_SERVER_BUFFER *SServ = NULL; +BOOL DlgOk; + + +/*+-------------------------------------------------------------------------+ + | BrowseListCompare() + | + +-------------------------------------------------------------------------+*/ +int __cdecl BrowseListCompare(const void *arg1, const void *arg2) { + SERVER_BROWSE_BUFFER *SLarg1, *SLarg2; + + SLarg1 = (SERVER_BROWSE_BUFFER *) arg1; + SLarg2 = (SERVER_BROWSE_BUFFER *) arg2; + + // This works as the first item of the structure is the string + return lstrcmpi( SLarg1->Name, SLarg2->Name); + +} // BrowseListCompare + + +/*+-------------------------------------------------------------------------+ + | BrowseListInit() + | + +-------------------------------------------------------------------------+*/ +void BrowseListInit(HWND hDlg, int ServerType) { + SERVER_BROWSE_BUFFER *SList; + DWORD Status; + DWORD Count; + DWORD Index; + DWORD i; + HWND hCtrl; + + switch (BrowseType) { + case BROWSE_TYPE_NT: + Status = NTServerEnum(NULL, &ServList); + break; + + case BROWSE_TYPE_NW: + Status = NWServerEnum(NULL, &ServList); + break; + } + + if (ServList) { + Count = ServList->Count; + SList = ServList->SList; + + // Sort the server list before putting it in the dialog + qsort((void *) SList, (size_t) Count, sizeof(SERVER_BROWSE_BUFFER), BrowseListCompare); + + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + for (i = 0; i < Count; i++) { + Index = i; + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) Index); + } + + } + +} // BrowseListInit + + +/*+-------------------------------------------------------------------------+ + | BrowseListFree() + | + +-------------------------------------------------------------------------+*/ +void BrowseListFree(SERVER_BROWSE_LIST *ServList) { + DWORD i; + DWORD Count; + SERVER_BROWSE_BUFFER *SList; + + if (!ServList) + return; + + SList = ServList->SList; + Count = ServList->Count; + for (i = 0; i < Count; i++) + if (SList[i].child) + FreeMemory((LPBYTE) SList[i].child); + + FreeMemory((LPBYTE) ServList); + ServList = NULL; + +} // BrowseListFree + + +/*+-------------------------------------------------------------------------+ + | DlgServSel_Do() + | + +-------------------------------------------------------------------------+*/ +int DlgServSel_Do(int BType, HWND hwndOwner) { + int result; + DLGPROC lpfndp; + + BrowseType = BType; + + // Init the Hier Draw stuff - Need to do this here so we have a value + // for WM_MEASUREITEM which is sent before the WM_INITDIALOG message + HierDraw_DrawInit(hInst, IDR_LISTICONS, ROWS, COLS, FALSE, &HierDrawStruct, TRUE ); + + lpfndp = (DLGPROC)MakeProcInstance((FARPROC)DlgServSel, hInst); + result = DialogBox(hInst, TEXT("DlgServSel"), hwndOwner, lpfndp) ; + + FreeProcInstance((FARPROC)lpfndp); + HierDraw_DrawTerm(&HierDrawStruct); + + return result; +} // DlgServSel_Do + + + +/*+-------------------------------------------------------------------------+ + | BrowseListFind() + | + +-------------------------------------------------------------------------+*/ +SERVER_BROWSE_BUFFER *BrowseListFind(DWORD dwData) { + DWORD ContainerNum; + DWORD Index = 0; + SERVER_BROWSE_LIST *ServerSubList; + + Index = LOWORD(dwData); + ContainerNum = HIWORD(dwData); + + if (!ContainerNum) + return(&ServList->SList[Index]); + else { + ContainerNum--; // Adjust for 0 index + ServerSubList = (SERVER_BROWSE_LIST *) ServList->SList[ContainerNum].child; + return(&ServerSubList->SList[Index]); + } + +} // BrowseListFind + + +/*+-------------------------------------------------------------------------+ + | DlgServSel_OnDrawItem() + | + +-------------------------------------------------------------------------+*/ +VOID DlgServSel_OnDrawItem(HWND hwnd, DRAWITEMSTRUCT FAR* lpDrawItem) { + TCHAR szText[MAX_PATH + 1]; + DWORD dwData; + int nLevel = 0; + int nRow = 0; + int nColumn = 0; + DWORD dwConnectLevel = 0; + SERVER_BROWSE_BUFFER *SList; + + // if there is nothing to browse then don't need to draw anything. + if (ServList == NULL) + return; + + dwData = lpDrawItem->itemData; + + SList = BrowseListFind(dwData); + + // if there is a double back-slash then trim it off... + if ((SList->Name[0] == TEXT('\\')) && (SList->Name[1] == TEXT('\\'))) + lstrcpy(szText, &(SList->Name[2])); + else + lstrcpy(szText, SList->Name); + + // Select the correct icon, open folder, closed folder, or document. + switch(BrowseType) { + case BROWSE_TYPE_NT: + break; + + case BROWSE_TYPE_NW: + nRow = 1; + break; + + } + + // Can this item be opened ? + if (SList->Container) { + + // Is it open ? + if ( HierDraw_IsOpened(&HierDrawStruct, dwData) ) + nColumn = 1; + else + nColumn = 0; + } + else { + if (!IsNetWareBrowse) + nLevel = 1; + + nColumn = 2; + } + + // All set to call drawing function. + HierDraw_OnDrawItem(hwnd, lpDrawItem, nLevel, dwConnectLevel, szText, nRow, nColumn, &HierDrawStruct); + + return; + +} // DlgServSel_OnDrawItem + + + +/*+-------------------------------------------------------------------------+ + | DlgServSel_OnCommand() + | + +-------------------------------------------------------------------------+*/ +BOOL DlgServSel_OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) { + int wmId, wmEvent; + WORD wItemNum; + DWORD dwData; + HWND hCtrl; + TCHAR ServerName[MAX_NW_OBJECT_NAME_LEN + 1]; + HWND hParent; + SERVER_BROWSE_BUFFER *SList; + + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + + if (wItemNum != (WORD) LB_ERR) { + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if (dwData != LB_ERR) + DlgServSel_ActionItem(hCtrl, dwData, (WORD) wItemNum); + } + break; + + case IDC_ALTOK: + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + * (WORD *)ServerName = sizeof(ServerName); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) ServerName); + + CanonServerName((LPTSTR) ServerName); + + hParent = GetWindow (hDlg, GW_OWNER); + + if (IsNetWareBrowse) + hCtrl = GetDlgItem(hParent, IDC_EDITNWSERV); + else + hCtrl = GetDlgItem(hParent, IDC_EDITNTSERV); + + SendMessage(hCtrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) ServerName); + EndDialog(hDlg, 0); + break; + + case ID_INIT: + SetFocus(GetDlgItem(hDlg, IDC_EDIT1)); + break; + + case IDCANCEL: + EndDialog(hDlg, 0); + break; + + case IDHELP: + switch (BrowseType) { + case BROWSE_TYPE_NT: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_BROWSENT); + break; + + case BROWSE_TYPE_NW: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_BROWSENW); + break; + + } + break; + + case IDC_CHKUSERS: + break; + + case IDC_LOADNWSERV: + BrowseListInit(hDlg, SERVER_TYPE_NW); + break; + + case IDC_LOADNTSERV: + BrowseListInit(hDlg, SERVER_TYPE_NT); + break; + + case IDC_LOADDOMAIN: + BrowseListInit(hDlg, SERVER_TYPE_NT); + break; + + case ID_SETSEL: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + + if (wItemNum != (WORD) LB_ERR) { + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if (dwData != LB_ERR) { + SList = BrowseListFind(dwData); + + // Is this an item or folder + if (!SList->Container) { + // is a server - so put it up in edit box + if (SList->Name[0] == TEXT('\\') && SList->Name[1] == TEXT('\\')) + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) &SList->Name[2]); + else + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) SList->Name); + + hCtrl = GetDlgItem(hDlg, IDC_ALTOK); + EnableWindow(hCtrl, TRUE); + } else { + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) TEXT("")); + hCtrl = GetDlgItem(hDlg, IDC_ALTOK); + EnableWindow(hCtrl, FALSE); + } + } + } + break; + + case IDC_LIST1: + + switch (wmEvent) { + case LBN_DBLCLK: + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L); + + if (wItemNum != (WORD) LB_ERR) { + dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L); + + if (dwData != LB_ERR) + DlgServSel_ActionItem(hCtrl, dwData, wItemNum); + } + break; + + case LBN_SELCHANGE: + PostMessage(hDlg, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + } + break; + + case IDC_EDIT1: + + if (wmEvent == EN_CHANGE) { + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) { + hCtrl = GetDlgItem(hDlg, IDC_ALTOK); + EnableWindow(hCtrl, TRUE); + } else { + hCtrl = GetDlgItem(hDlg, IDC_ALTOK); + EnableWindow(hCtrl, FALSE); + } + + } + + break; + + default: + return FALSE; + + } + + return TRUE; +} // DlgServSel_OnCommand + + + +/*+-------------------------------------------------------------------------+ + | DlgServSel_ActionItem() + | + +-------------------------------------------------------------------------+*/ +VOID DlgServSel_ActionItem(HWND hWndList, DWORD dwData, WORD wItemNum) { + DWORD dwIncr; + DWORD Parent; + DWORD Status; + DWORD Count; + SERVER_BROWSE_BUFFER *SList; + SERVER_BROWSE_LIST *SubList; + DWORD wItem, wCount, dwAddItem; + + if (dwData == LB_ERR) + return; + + SList = BrowseListFind(dwData); + + // Is this an item or folder + if (!SList->Container) { + // is a server - so put it up in edit box + if (SList->Name[0] == TEXT('\\') && SList->Name[1] == TEXT('\\')) + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) &SList->Name[2]); + else + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) SList->Name); + + PostMessage(hParent, WM_COMMAND, (WPARAM) IDC_ALTOK, (LPARAM) 0); + + } + else { + SendMessage(hEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) TEXT("")); + + // Is it open ? + if ( HierDraw_IsOpened(&HierDrawStruct, dwData) ) { + + // It's open ... Close it + HierDraw_CloseItem(&HierDrawStruct, dwData); + + // Remove the child items. Close any children that are + // open on the way. + + // wItem can stay constant as we are moveing stuff up in the listbox as we + // are deleting. + wItemNum++; + dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L); + SList = BrowseListFind(dwIncr); + + while (!SList->Container) { + SendMessage(hWndList, LB_DELETESTRING, wItemNum, 0L); + dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L); + SList = BrowseListFind(dwIncr); + } + + Parent = HIWORD(dwIncr); + if (Parent) { + Parent--; + SList = BrowseListFind(Parent); + FreeMemory((LPBYTE) SList->child); + SList->child = NULL; + } + + } + else { + + // It's closed ... Open it + HierDraw_OpenItem(&HierDrawStruct, dwData); + + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0L); // Disable redrawing. + + CursorHourGlass(); + + // Enumerate the servers in this container (domain) + Status = NTServerEnum(SList->Name, (SERVER_BROWSE_LIST **) &SList->child); + + if (!Status) { + Parent = LOWORD(dwData); + SubList = (SERVER_BROWSE_LIST *) SList->child; + Count = SubList->Count; + SList = SubList->SList; + + // Sort the server list before putting it in the dialog + qsort((void *) SList, (size_t) Count, sizeof(SERVER_BROWSE_BUFFER), BrowseListCompare); + + for (wItem = wItemNum, wCount = 0, wItem++; + wCount < SubList->Count; wItem++, wCount++) { + dwAddItem = ((Parent + 1) << 16) + wCount; + SendMessage(hWndList, LB_INSERTSTRING, wItem, dwAddItem); + } + + } + + // Make sure as many child items as possible are showing + HierDraw_ShowKids(&HierDrawStruct, hWndList, (WORD) wItemNum, (WORD) SubList->Count ); + + CursorNormal(); + + SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L); // Enable redrawing. + InvalidateRect(hWndList, NULL, TRUE); // Force redraw + } + } + +} // DlgServSel_ActionItem + + +/*+-------------------------------------------------------------------------+ + | ServerListScan() + | + | Given a key, scans the list of servers to find a matching first + | letter in the server name. + | + +-------------------------------------------------------------------------+*/ +WORD ServerListScan(HWND hWnd, DWORD dwData, TCHAR Key) { + BOOL Found = FALSE; + WORD wItemNum; + DWORD dwFindItem; + DWORD dwData2; + DWORD ContainerNum; + WORD Index = 0; + DWORD Count = 0; + SERVER_BROWSE_LIST *ptrServList; + SERVER_BROWSE_BUFFER *SList; + + Index = LOWORD(dwData); + ContainerNum = HIWORD(dwData); + + // Get the head of the Server list for the current item + if (!ContainerNum) + ptrServList = ServList; + else { + ptrServList = (SERVER_BROWSE_LIST *) ServList->SList[ContainerNum-1].child; + } + + // Now iterate down through the list trying to find the key... + SList = ptrServList->SList; + while ((!Found) && (Count < ptrServList->Count)) { + if (SList[Count].Name[0] == Key) { + dwFindItem = Count; + Found = TRUE; + } else + Count++; + } + + // If we found the key now have to find the appropriate index value + if (Found && (Index != Count)) { + // Fix up the new item data to find + if (ContainerNum) + dwFindItem += (ContainerNum << 16); + + wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + Found = FALSE; + if (Index < Count) { + // search forward in list + dwData2 = 0; + while ((dwData2 != LB_ERR) && !Found) { + dwData2 = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + + if (dwData2 == dwFindItem) + Found = TRUE; + else + wItemNum++; + + } + } else { + // search backwards in list + Count = Index; + while ((wItemNum > 0) && !Found) { + wItemNum--; + dwData2 = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L); + Count--; + + if (dwData2 == dwFindItem) + Found = TRUE; + } + } + } else + return (Index); + + if (Found) + return(wItemNum); + else + return (Index); + +} // ServerListScan + + + +static WNDPROC _wpOrigWndProc; +#define LISTBOX_COUNT 13 + +/*+-------------------------------------------------------------------------+ + | ListSubClassProc() + | + | Handles key processing for the hierarchical listbox. Specifically + | the up/down arrow keys and the letter keys. + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK ListSubClassProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + LRESULT lResult = 0; + BOOL fCallOrigProc = TRUE; + DWORD wItemNum; + DWORD wNewNum; + DWORD dwData; + + switch (message) { + + case WM_KEYDOWN: + wItemNum = (DWORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L); + if (wItemNum != (DWORD) LB_ERR) + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, (WPARAM) wItemNum, 0L); + else { + wItemNum = 0; + SendMessage(hWnd, LB_SETCURSEL, (WPARAM) 0, 0L); + dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, (WPARAM) wItemNum, 0L); + + if ((dwData == LB_ERR) || (dwData == LB_ERR)) + break; + } + + fCallOrigProc = FALSE; + + switch (LOWORD(wParam)) { + + case VK_PRIOR: + if (wItemNum > LISTBOX_COUNT) + wNewNum = wItemNum - LISTBOX_COUNT; + else + wNewNum = 0; + + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wNewNum, 0L); + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_NEXT: + wItemNum = wItemNum + LISTBOX_COUNT; + wNewNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L); + + if (wItemNum < wNewNum) + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + else + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wNewNum - 1), 0L); + + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_END: + wItemNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L); + + if (wItemNum != LB_ERR) + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wItemNum - 1), 0L); + + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_HOME: + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) 0, 0L); + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_UP: + if (wItemNum > 0) { + wItemNum--; + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + } + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_DOWN: + wItemNum++; + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + case VK_F1: + fCallOrigProc = TRUE; + break; + + default: + wItemNum = ServerListScan(hWnd, dwData, (TCHAR) wParam); + PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L); + PostMessage(hParent, WM_COMMAND, (WPARAM) ID_SETSEL, 0L); + break; + + } + + break; + + } + + if (fCallOrigProc) + lResult = CallWindowProc(_wpOrigWndProc, hWnd, message, wParam, lParam); + + return (lResult); + +} // ListSubClassProc + + + +/*+-------------------------------------------------------------------------+ + | DlgServSel() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgServSel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + + switch (message) { + + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + hParent = hDlg; + + // Disable the Add button until server is selected + hCtrl = GetDlgItem(hDlg, IDC_ALTOK); + EnableWindow(hCtrl, FALSE); + + // subclass listbox handler + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + _wpOrigWndProc = SubclassWindow(hCtrl, ListSubClassProc); + + switch (BrowseType) { + case BROWSE_TYPE_NT: + PostMessage(hDlg, WM_COMMAND, IDC_LOADNTSERV, 0); + lstrcpy( NetProvider, NT_PROVIDER); + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_NT_SERVER_NAME_LEN, 0); + break; + + case BROWSE_TYPE_NW: + lstrcpy( NetProvider, NW_PROVIDER); + SetWindowText(hDlg, Lids(IDS_S_35)); + PostMessage(hDlg, WM_COMMAND, IDC_LOADNWSERV, 0); + hCtrl = GetDlgItem(hDlg, IDC_EDIT1); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_NW_OBJECT_NAME_LEN, 0); + break; + + } + + hEdit = GetDlgItem(hDlg, IDC_EDIT1); + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0); + return (TRUE); + + case WM_DESTROY: + BrowseListFree(ServList); + break; + + case WM_SETFONT: + // Set the text height + HierDraw_DrawSetTextHeight(GetDlgItem(hDlg, IDC_LIST1), (HFONT)wParam, &HierDrawStruct); + + break; + + case WM_COMMAND: + return DlgServSel_OnCommand(hDlg, wParam, lParam); + + case WM_DRAWITEM: + DlgServSel_OnDrawItem(hDlg, (DRAWITEMSTRUCT FAR*)(lParam)); + return TRUE; + break; + + case WM_MEASUREITEM: + HierDraw_OnMeasureItem(hDlg, (MEASUREITEMSTRUCT FAR*)(lParam), &HierDrawStruct); + return TRUE; + break; + + } + + return (FALSE); + + lParam; + +} // DlgServSel + + +/*+-------------------------------------------------------------------------+ + | DlgGetServ_OnInitDialog() + | + +-------------------------------------------------------------------------+*/ +BOOL DlgGetServ_OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lParam) { + HWND hCtrl; + + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // Disable the Add button until both servers are selected + hCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hCtrl, FALSE); + + hCtrl = GetDlgItem(hDlg, IDC_EDITNWSERV); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_NW_OBJECT_NAME_LEN, 0); + hCtrl = GetDlgItem(hDlg, IDC_EDITNTSERV); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_NT_SERVER_NAME_LEN, 0); + PostMessage(hDlg, WM_COMMAND, ID_INIT, 0); + return (TRUE); + +} // DlgGetServ_OnInitDialog + + +/*+-------------------------------------------------------------------------+ + | MapShare() + | + +-------------------------------------------------------------------------+*/ +// CODEWORK: This routine can be condensed - all the virtual add share stuff +// can be compacted to a subroutine +BOOL MapShare(SHARE_BUFFER *Share, DEST_SERVER_BUFFER *DServ) { + static TCHAR Path[MAX_PATH + 1]; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + SHARE_BUFFER *MatchShare; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *DList; + DRIVE_BUFFER *MaxNTFS = NULL; + DRIVE_BUFFER *MaxFAT = NULL; + BOOL Match = FALSE; + BOOL NTFS = FALSE; + BOOL Virtual = FALSE; + DWORD i; + + // First see if there is a 1:1 share correspondence already in existance + + // the normal shares first... + ShareList = DServ->ShareList; + SList = ShareList->SList; + + if (ShareList != NULL) + for (i = 0; ((i < ShareList->Count) && (!Match)); i++) { + if (!lstrcmpi(SList[i].Name, Share->Name)) { + MatchShare = &SList[i]; + Match = TRUE; + } + } // match normal share 1:1 + + if (!Match) { + VShare = DServ->VShareStart; + + while(VShare && !Match) { + if (!lstrcmpi(VShare->Name, Share->Name)) { + // will use VShare to point to matched share + Virtual = TRUE; + Match = TRUE; + } else + VShare = VShare->next; + } + } // match VShare 1:1 + + if (!Match) { + // No match so make share name the same - try to find NTFS drive with + // enough room to put it on. + DList = DServ->DriveList->DList; + if (DList != NULL) + for (i = 0; ((i < DServ->DriveList->Count) && (!Match)); i++) { + if (DList[i].Type == DRIVE_TYPE_NTFS) { + // Find our Max NTFS + if (!MaxNTFS) + MaxNTFS = &DList[i]; + else + if ( (MaxNTFS->FreeSpace - MaxNTFS->AllocSpace) < (DList[i].FreeSpace - DList[i].AllocSpace) ) + MaxNTFS = &DList[i]; + + // Is an NTFS Drive - check for space + if ((DList[i].FreeSpace - DList[i].AllocSpace) > Share->Size) { + // Checks out - create a new virutal share for this + Match = TRUE; + Virtual = TRUE; + wsprintf(Path, TEXT("%s:\\%s"), DList[i].Drive, Share->Name); + VShare = VShareListAdd(DServ, Share->Name, Path); + VShare->Drive = &DList[i]; + } + } + } + } // match new NTFS share + + if (!Match) { + // No NTFS drive so try other drives... + DList = DServ->DriveList->DList; + if (DList != NULL) + for (i = 0; ((i < DServ->DriveList->Count) && (!Match)); i++) { + if (DList[i].Type != DRIVE_TYPE_NTFS) { + // Find our Max FAT + if (!MaxFAT) + MaxFAT = &DList[i]; + else + if ( (MaxFAT->FreeSpace - MaxFAT->AllocSpace) < (DList[i].FreeSpace - DList[i].AllocSpace) ) + MaxFAT = &DList[i]; + + // Is an other Drive - check for space + if ((DList[i].FreeSpace - DList[i].AllocSpace) > Share->Size) { + // Checks out - create a new virutal share for this + Match = TRUE; + Virtual = TRUE; + wsprintf(Path, TEXT("%s:\\%s"), DList[i].Drive, Share->Name); + VShare = VShareListAdd(DServ, Share->Name, Path); + VShare->Drive = &DList[i]; + } + } + } + } // match new FAT share + + if (!Match) { + // we are going to assign some virtual share for this + Virtual = TRUE; + + // use max space for NTFS else FAT + if (MaxNTFS) { + // if also have some fat partitions if they have more space use them + if (!(MaxFAT && ( (MaxNTFS->FreeSpace - MaxNTFS->AllocSpace) < (MaxFAT->FreeSpace - MaxFAT->AllocSpace) ))) { + Match = TRUE; + wsprintf(Path, TEXT("%s:\\%s"), MaxNTFS->Drive, Share->Name); + VShare = VShareListAdd(DServ, Share->Name, Path); + VShare->Drive = MaxNTFS; + } + } + + // if we couldn't match with NTFS then use other drive types + if (!Match) { + Match = TRUE; + wsprintf(Path, TEXT("%s:\\%s"), MaxFAT->Drive, Share->Name); + VShare = VShareListAdd(DServ, Share->Name, Path); + VShare->Drive = MaxFAT; + } + + } // match anything!!! + + if (Match) { + // Have the match so adjust the params + if (!Virtual) { + Share->Virtual = FALSE; + Share->DestShare = MatchShare; + + // if there is no drive specified (can be the case if the share points + // to an invalid drive - like a floppy) then we skip out and ignore it + // for right now. We will alert the user when they try to do the + // transfer. + if (MatchShare->Drive == NULL) + return TRUE; + + MatchShare->Drive->AllocSpace += Share->Size; +#ifdef DEBUG +dprintf(TEXT("Matched Share: %s -> %s\n"), Share->Name, MatchShare->Name); +#endif + } else { + Share->Virtual = TRUE; + Share->DestShare = (SHARE_BUFFER *) VShare; + VShare->Drive->AllocSpace += Share->Size; + VShare->UseCount++; +#ifdef DEBUG +dprintf(TEXT("Matched Virtual Share: %s -> %s\n"), Share->Name, VShare->Path); +#endif + } + + return TRUE; + } else { +#ifdef DEBUG +dprintf(TEXT("Couldn't Map Share: %s\n"), Share->Name); +#endif + // Bad news - the destination server just can't handle this! + return FALSE; + } + +} // MapShare + + +/*+-------------------------------------------------------------------------+ + | ShareListInit() + | + +-------------------------------------------------------------------------+*/ +void ShareListInit(SHARE_LIST *ShareList, DEST_SERVER_BUFFER *DServ) { + SHARE_BUFFER *SList; + DWORD i; + + // Mark that we want to convert all the shares + if (ShareList != NULL) { + SList = ShareList->SList; + ShareList->ConvertCount = ShareList->Count; + + for (i = 0; i < ShareList->Count; i++) { + if (MapShare(&SList[i], DServ)) + SList[i].Convert = TRUE; + } + } + +} // ShareListInit + + +/*+-------------------------------------------------------------------------+ + | DlgGetServ_OnCommand() + | + +-------------------------------------------------------------------------+*/ +BOOL DlgGetServ_OnCommand(HWND hDlg, int wmId, HWND hwndCtl, UINT wmEvent) { + HWND hCtrl; + BOOL Enable = FALSE; + + switch (wmId) { + case IDOK: + hCtrl = GetDlgItem(hDlg, IDC_EDITNWSERV); + * (WORD *)SourceServer = sizeof(SourceServer); + * (WORD *)DestServer = sizeof(DestServer); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) SourceServer); + hCtrl = GetDlgItem(hDlg, IDC_EDITNTSERV); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) DestServer); + + CanonServerName(SourceServer); + CanonServerName(DestServer); + + if ( NWServerValidate(hDlg, SourceServer, TRUE) ) { + if ( NTServerValidate(hDlg, DestServer) ) { + // Check if we need to add server to server list + DServ = DServListFind(DestServer); + + if (DServ == NULL) { + DServ = DServListAdd(DestServer); + NTServerInfoSet(hDlg, DestServer, DServ); + } else + DServ->UseCount++; + + SServ = SServListFind(SourceServer); + + if (SServ == NULL) { + SServ = SServListAdd(SourceServer); + NWServerInfoSet(SourceServer, SServ); + ShareListInit(SServ->ShareList, DServ); + } + + DlgOk = TRUE; + EndDialog(hDlg, 0); + } else { + // Clean up connections that the Validation routines made + NWUseDel(SourceServer); + NTUseDel(DestServer); + hCtrl = GetDlgItem(hDlg, IDC_EDITNTSERV); + SetFocus(hCtrl); + } + } else { + // Clean up use validation routine made + NWUseDel(SourceServer); + hCtrl = GetDlgItem(hDlg, IDC_EDITNWSERV); + SetFocus(hCtrl); + } + + return (TRUE); + + case ID_INIT: + SetFocus(GetDlgItem(hDlg, IDC_EDITNWSERV)); + break; + + case IDCANCEL: + EndDialog(hDlg, 0); + DlgOk = FALSE; + return (TRUE); + break; + + case IDHELP: + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_ADD); + return (TRUE); + break; + + case IDC_NWBROWSE: + IsNetWareBrowse = TRUE; + DlgServSel_Do(BROWSE_TYPE_NW, hDlg); + return (TRUE); + break; + + case IDC_NTBROWSE: + IsNetWareBrowse = FALSE; + DlgServSel_Do(BROWSE_TYPE_NT, hDlg); + return (TRUE); + break; + + case IDC_EDITNWSERV: + case IDC_EDITNTSERV: + if (wmEvent == EN_CHANGE) { + hCtrl = GetDlgItem(hDlg, IDC_EDITNWSERV); + + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) { + hCtrl = GetDlgItem(hDlg, IDC_EDITNTSERV); + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) + Enable = TRUE; + } + + hCtrl = GetDlgItem(hDlg, IDOK); + if (Enable) + EnableWindow(hCtrl, TRUE); + else + EnableWindow(hCtrl, FALSE); + + } + break; + } + +} // DlgGetServ_OnCommand + + + +/*+-------------------------------------------------------------------------+ + | DlgGetServ() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgGetServ(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch (msg) { + HANDLE_MSG(hDlg, WM_INITDIALOG, DlgGetServ_OnInitDialog); + HANDLE_MSG(hDlg, WM_COMMAND, DlgGetServ_OnCommand); + + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgGetServ + + +/*+-------------------------------------------------------------------------+ + | DialogGetServ() + | + +-------------------------------------------------------------------------+*/ +DWORD DialogServerBrowse(HINSTANCE hInst, HWND hDlg, SOURCE_SERVER_BUFFER **lpSourceServer, DEST_SERVER_BUFFER **lpDestServer) { + DLGPROC lpfnDlg; + + SServListCurrent = NULL; + DServListCurrent = NULL; + SServ = NULL; + DServ = NULL; + + lpfnDlg = MakeProcInstance((DLGPROC)DlgGetServ, hInst); + DialogBox(hInst, TEXT("DlgGetServ"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + + if (DlgOk) { + *lpSourceServer = SServ; + *lpDestServer = DServ; + return 0; + } else + return 1; + +} // DialogServerBrowse diff --git a/private/nw/convert/nwconv/sbrowse.h b/private/nw/convert/nwconv/sbrowse.h new file mode 100644 index 000000000..efd7d6fdb --- /dev/null +++ b/private/nw/convert/nwconv/sbrowse.h @@ -0,0 +1,44 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HSBROWSE_ +#define _HSBROWSE_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#define BROWSE_TYPE_NT 0 +#define BROWSE_TYPE_NW 1 +#define BROWSE_TYPE_DOMAIN 2 + +/*+-------------------------------------------------------------------------+ + | Server Browsing Stuff | + +-------------------------------------------------------------------------+*/ +typedef struct _SERVER_BROWSE_BUFFER { + TCHAR Name[MAX_SERVER_NAME_LEN+1]; + TCHAR Description[MAX_PATH+1]; + BOOL Container; + struct _SERVER_BROWSE_LIST *child; // Points to a server list +} SERVER_BROWSE_BUFFER; + + +typedef struct _SERVER_BROWSE_LIST { + DWORD Count; + SERVER_BROWSE_BUFFER SList[]; +} SERVER_BROWSE_LIST; + + +/*+-------------------------------------------------------------------------+ + | Function Prototypes | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgServSel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +DWORD DialogServerBrowse(HINSTANCE hInst, HWND hDlg, SOURCE_SERVER_BUFFER **lpSourceServer, DEST_SERVER_BUFFER **lpDestServer); +int DlgServSel_Do(int BType, HWND hwndOwner); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/servlist.c b/private/nw/convert/nwconv/servlist.c new file mode 100644 index 000000000..97a272746 --- /dev/null +++ b/private/nw/convert/nwconv/servlist.c @@ -0,0 +1,2094 @@ +/* + +-------------------------------------------------------------------------+ + | Server Linked List Manipulation Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [ServList.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 15, 1994] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | Bunch of similar utility functions for adding to, deleting from, | + | saving and restoring data lists. | + | | + | | + | History: | + | arth Jun 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + +#include "globals.h" +#include "convapi.h" +#include "columnlb.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "userdlg.h" +#include "filedlg.h" + +// define from SBrowse.c -> for SourceShareListFixup +BOOL MapShare(SHARE_BUFFER *Share, DEST_SERVER_BUFFER *DServ); + +static ULONG NumDServs = 0; +static ULONG NumSServs = 0; +static ULONG NumDomains = 0; + +// Note: Most of these routines are a bunch of doubly-linked list functions +// as such it should be possible to condense them to use some common +// functions for add/delete/insert. However virtual-shares will have +// to be different as the Virtual BOOL has to be the first field. + + +/*+-------------------------------------------------------------------------+ + | Routines for Directory/File Trees | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | TreeSave() + | + +-------------------------------------------------------------------------+*/ +void _TreeSaveR(HANDLE hFile, DIR_BUFFER *Dir) { + DIR_BUFFER *DList; + ULONG Size; + ULONG i; + DWORD wrote; + + if (Dir == NULL) + return; + + // First save out the file list for this node + if (Dir->FileList) { + WriteFile(hFile, &Dir->FileList->Count, sizeof(Dir->FileList->Count), &wrote, NULL); + Size = sizeof(FILE_LIST) + (Dir->FileList->Count * sizeof(FILE_BUFFER)); + WriteFile(hFile, Dir->FileList, Size, &wrote, NULL); + } + + if (Dir->DirList) { + DList = Dir->DirList->DirBuffer; + + // first write out this dirlist then recurse down tree. + WriteFile(hFile, &Dir->DirList->Count, sizeof(Dir->DirList->Count), &wrote, NULL); + Size = sizeof(DIR_LIST) + (Dir->DirList->Count * sizeof(DIR_BUFFER)); + WriteFile(hFile, Dir->DirList, Size, &wrote, NULL); + + for (i = 0; i < Dir->DirList->Count; i++) + _TreeSaveR(hFile, &DList[i]); + + } + +} // _TreeSaveR + + +void TreeSave(HANDLE hFile, DIR_BUFFER *Dir) { + DWORD wrote; + + if (Dir == NULL) + return; + + // Make sure we save the minimum amount + TreePrune(Dir); + + // write out the actual dir + WriteFile(hFile, Dir, sizeof(DIR_BUFFER), &wrote, NULL); + + // now save it's child info recursively + _TreeSaveR(hFile, Dir); + +} // TreeSave + + +/*+-------------------------------------------------------------------------+ + | TreeLoad() + | + +-------------------------------------------------------------------------+*/ +void _TreeLoadR(HANDLE hFile, DIR_BUFFER *Dir) { + DIR_LIST *DList; + DIR_BUFFER *DBuff; + FILE_LIST *FList; + FILE_BUFFER *FBuff; + ULONG Size; + ULONG i; + DWORD wrote; + ULONG Count; + + if (Dir == NULL) + return; + + // First save out the file list for this node + if (Dir->FileList) { + ReadFile(hFile, &Count, sizeof(Count), &wrote, NULL); + Size = sizeof(FILE_LIST) + (sizeof(FILE_BUFFER) * Count); + FList = AllocMemory(Size); + ReadFile(hFile, FList, Size, &wrote, NULL); + + // Read it in, now fixup the internal pointers. + FList->parent = Dir; + + FBuff = FList->FileBuffer; + for (i = 0; i < FList->Count; i++) + FBuff[i].parent = FList; + + Dir->FileList = FList; + } + + if (Dir->DirList) { + ReadFile(hFile, &Count, sizeof(Count), &wrote, NULL); + Size = sizeof(DIR_LIST) + (sizeof(DIR_BUFFER) * Count); + DList = AllocMemory(Size); + ReadFile(hFile, DList, Size, &wrote, NULL); + + // Read it in, now fixup the internal pointers. + DList->parent = Dir; + + DBuff = DList->DirBuffer; + for (i = 0; i < DList->Count; i++) + DBuff[i].parent = DList; + + Dir->DirList = DList; + + // Now recurse into children and fix them up + for (i = 0; i < DList->Count; i++) + _TreeLoadR(hFile, &DBuff[i]); + + } + +} // _TreeLoadR + + +void TreeLoad(HANDLE hFile, DIR_BUFFER **pDir) { + DIR_BUFFER *Dir; + DWORD wrote; + + if (pDir == NULL) + return; + + // Allocate space for the new root + Dir = AllocMemory(sizeof(DIR_BUFFER)); + if (Dir == NULL) + return; + + memset(Dir, 0, sizeof(DIR_BUFFER)); + + // set passed in var to new memory and read in values from file + *pDir = Dir; + ReadFile(hFile, Dir, sizeof(DIR_BUFFER), &wrote, NULL); + + // now recursively load child information + _TreeLoadR(hFile, Dir); + +} // TreeLoad + + +/*+-------------------------------------------------------------------------+ + | Routines for User Lists | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | UserListCompare() + | + +-------------------------------------------------------------------------+*/ +int __cdecl UserListCompare(const void *arg1, const void *arg2) { + USER_BUFFER *ULarg1, *ULarg2; + + ULarg1 = (USER_BUFFER *) arg1; + ULarg2 = (USER_BUFFER *) arg2; + + // This works as the first item of the structure is the string + return lstrcmpi( ULarg1->Name, ULarg2->Name); + +} // UserListCompare + + +/*+-------------------------------------------------------------------------+ + | Routines for Share Lists | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ShareListDelete() + | + +-------------------------------------------------------------------------+*/ +void ShareListDelete(SHARE_LIST *ShareList) { + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + ULONG i; + + if (ShareList == NULL) + return; + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + if (SList[i].Root != NULL) { + TreeDelete(SList[i].Root); + FreeMemory(SList[i].Root); + } + + // Note: SList[i].Drive points to a dest server drive, so we don't + // free it here. + if (!ShareList->Fixup) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + + if ((VShare != NULL) && VShare->UseCount) + VShare->UseCount--; + } + + } + +} // ShareListDelete + + +/*+-------------------------------------------------------------------------+ + | SourceShareListFixup() + | + +-------------------------------------------------------------------------+*/ +void SourceShareListFixup(DEST_SERVER_BUFFER *DServ, SHARE_LIST *ShareList) { + TCHAR tmpName[MAX_SHARE_NAME_LEN + 1]; + SHARE_BUFFER *SList; + ULONG i; + DWORD *VMap = NULL; + + if (ShareList == NULL) + return; + + ShareList->Fixup = FALSE; + // Generate Virtual Share Map + VShareListIndexMapGet(DServ, &VMap); + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + if (SList[i].DestShare != NULL) + if (SList[i].Virtual) + SList[i].DestShare = (SHARE_BUFFER *) VMap[(DWORD) SList[i].DestShare - 1]; + else { + // Not a virtual share - now need to take name from path and rematch it + // to the new destination share list (dest sharename was stored in + // path in the ShareListSave routine). + lstrcpy(tmpName, SList[i].Name); + lstrcpy(SList[i].Name, SList[i].Path); + + // clear out path and the old DestShare + memset(SList[i].Path, 0, sizeof(SList[i].Path)); + SList[i].DestShare = NULL; + + // Now map it to a dest share + MapShare(&SList[i], DServ); + + // Restore real name + lstrcpy(SList[i].Name, tmpName); + } + } + + if (VMap != NULL) + FreeMemory(VMap); + +} // SourceShareListFixup + + +/*+-------------------------------------------------------------------------+ + | DestShareListFixup() + | + +-------------------------------------------------------------------------+*/ +void DestShareListFixup(DEST_SERVER_BUFFER *DServ) { + SHARE_BUFFER *SList, *oSList; + SHARE_LIST *oShareList; + ULONG i, oi; + DRIVE_LIST *DList; + DRIVE_BUFFER *DBuff; + BOOL match; + + if (DServ->ShareList == NULL) + return; + + if (DServ->ShareList->Fixup == FALSE) + return; // do not fixup twice... + + DServ->ShareList->Fixup = FALSE; + DList = DServ->DriveList; + DBuff = DList->DList; + + oShareList = DServ->ShareList; + NTSharesEnum(&DServ->ShareList, DServ->DriveList); + if (DServ->ShareList == NULL) + return; + + SList = DServ->ShareList->SList; + oSList = oShareList->SList; + for (i = 0; i < DServ->ShareList->Count; i++) { + match = FALSE; + oi = 0; + + while ((!match) && (oi < oShareList->Count)) { + if (!lstrcmpi(SList[i].Name, oSList[oi].Name)) { + SList[i].Convert = oSList[oi].Convert; + SList[i].HiddenFiles = oSList[oi].HiddenFiles; + SList[i].SystemFiles = oSList[oi].SystemFiles; + match = TRUE; + } + + oi++; + } + + } + + FreeMemory(oShareList); + +} // DestShareListFixup + + +/*+-------------------------------------------------------------------------+ + | ShareListSave() + | + +-------------------------------------------------------------------------+*/ +void ShareListSave(HANDLE hFile, SHARE_LIST *ShareList) { + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + DWORD wrote; + ULONG Size, i; + DWORD *sb = NULL; + + if (ShareList == NULL) + return; + + Size = sizeof(SHARE_LIST) + (ShareList->Count * sizeof(SHARE_BUFFER)); + WriteFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + // Need to make a temp array to hold DestShare info + sb = AllocMemory(ShareList->Count * sizeof(DWORD)); + + SList = ShareList->SList; + + // Copy DestShares to temp holding place and replace them with + // their index + for (i = 0; i < ShareList->Count; i++) { + sb[i] = (DWORD) SList[i].DestShare; + + if (SList[i].DestShare != NULL) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + SList[i].DestShare = (SHARE_BUFFER *) (VShare->Index + 1); + } else { + // put the dest sharename into the path (temporarily) so that on load + // we have the name to match to the new share list. Can't match just + // the sharename to dest-sharename as the admin may have pointed it to + // a new one. + lstrcpy(SList[i].Path, SList[i].DestShare->Name); + SList[i].DestShare = (SHARE_BUFFER *) (SList[i].DestShare->Index + 1); + } + } + + ShareList->Fixup = TRUE; + WriteFile(hFile, ShareList, Size, &wrote, NULL); + ShareList->Fixup = FALSE; + + // Restore DestShare pointers + for (i = 0; i < ShareList->Count; i++) + SList[i].DestShare = (SHARE_BUFFER *) sb[i]; + + + if (sb != NULL) + FreeMemory(sb); + + // Share list array is saved out - now save out linked information + for (i = 0; i < ShareList->Count; i++) + if (SList[i].Root != NULL) + TreeSave(hFile, SList[i].Root); + +} // ShareListSave + + +/*+-------------------------------------------------------------------------+ + | ShareListLoad() + | + +-------------------------------------------------------------------------+*/ +void ShareListLoad(HANDLE hFile, SHARE_LIST **lpShareList) { + SHARE_BUFFER *SList; + SHARE_LIST *ShareList; + ULONG Size, i; + DWORD wrote; + + // Get how long this record is + ReadFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + ShareList = AllocMemory(Size); + if (ShareList == NULL) + return; + + ReadFile(hFile, ShareList, Size, &wrote, NULL); + + // Share list array is read in - now load linked information + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) + if (SList[i].Root != NULL) { + SList[i].Root = NULL; + TreeLoad(hFile, &SList[i].Root); + } + + *lpShareList = ShareList; + +#ifdef DEBUG +dprintf(TEXT("\n")); +dprintf(TEXT(" Number of Entries: %lu\n\n"), ShareList->Count); + +for (i = 0; i < ShareList->Count; i++) { + dprintf(TEXT(" Name: %s\n"), SList[i].Name); + dprintf(TEXT(" Path: %s\n"), SList[i].Path); +} +dprintf(TEXT("\n")); +#endif + +} // ShareListLoad + + +/*+-------------------------------------------------------------------------+ + | ShareListLog() + | + +-------------------------------------------------------------------------+*/ +void ShareListLog(SHARE_LIST *ShareList, BOOL DestServer) { + ULONG i; + + if ((ShareList == NULL) || (ShareList->Count == 0)) + return; + + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(1, Lids(IDS_L_125)); + + for (i = 0; i < ShareList->Count; i++) { + LogWriteLog(2, TEXT("%s\r\n"), ShareList->SList[i].Name); + + if (DestServer) + LogWriteLog(3, Lids(IDS_L_8), ShareList->SList[i].Path); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // ShareListLog + + +/*+-------------------------------------------------------------------------+ + | Routines for Source Server List | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | SServListAdd() + | + +-------------------------------------------------------------------------+*/ +SOURCE_SERVER_BUFFER *SServListAdd(LPTSTR ServerName) { + SOURCE_SERVER_BUFFER *tmpPtr; + ULONG Size; + + Size = sizeof(SOURCE_SERVER_BUFFER) + ((lstrlen(ServerName) + 3) * sizeof(TCHAR)); + tmpPtr = AllocMemory(Size); + + if (tmpPtr != NULL) { + // init it to NULL's + memset(tmpPtr, 0, Size); + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(SOURCE_SERVER_BUFFER)); + tmpPtr->LName = tmpPtr->Name; + lstrcpy(tmpPtr->Name, TEXT("\\\\")); + tmpPtr->Name += 2; + lstrcpy(tmpPtr->Name, ServerName); + + // link it into the list + if (!SServListStart) + SServListStart = SServListEnd = tmpPtr; + else { + SServListEnd->next = tmpPtr; + tmpPtr->prev = SServListEnd; + SServListEnd = tmpPtr; + } + + NumSServs++; + } + + return (tmpPtr); + +} // SServListAdd + + +/*+-------------------------------------------------------------------------+ + | SServListDelete() + | + +-------------------------------------------------------------------------+*/ +void SServListDelete(SOURCE_SERVER_BUFFER *tmpPtr) { + SOURCE_SERVER_BUFFER *PrevPtr; + SOURCE_SERVER_BUFFER *NextPtr; + + if (tmpPtr == NULL) + return; + + // Delete any attached share list first + ShareListDelete(tmpPtr->ShareList); + + // Free any admin share we made + NWUseDel(tmpPtr->Name); + + // Now unlink the actual server record + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (SServListEnd == tmpPtr) + SServListEnd = PrevPtr; + + // Check if at start of list + if (SServListStart == tmpPtr) + SServListStart = NextPtr; + + FreeMemory(tmpPtr); + NumSServs--; + + if (!NumSServs) + SServListStart = SServListEnd = NULL; + +} // SServListDelete + + +/*+-------------------------------------------------------------------------+ + | SServListDeleteAll() + | + +-------------------------------------------------------------------------+*/ +void SServListDeleteAll() { + SOURCE_SERVER_BUFFER *ServList; + SOURCE_SERVER_BUFFER *ServListNext; + + // Now remove the entries from the internal list + ServList = SServListStart; + + while (ServList) { + ServListNext = ServList->next; + SServListDelete(ServList); + ServList = ServListNext; + } + +} // SServListDeleteAll + + +/*+-------------------------------------------------------------------------+ + | SServListFind() + | + +-------------------------------------------------------------------------+*/ +SOURCE_SERVER_BUFFER *SServListFind(LPTSTR ServerName) { + BOOL Found = FALSE; + SOURCE_SERVER_BUFFER *ServList; + + ServList = SServListStart; + + while ((ServList && !Found)) { + if (!lstrcmpi(ServList->Name, ServerName)) + Found = TRUE; + else + ServList = ServList->next; + } + + if (!Found) + ServList = NULL; + + return (ServList); + +} // SServListFind + + +/*+-------------------------------------------------------------------------+ + | SServListIndex() + | + | The index routines place an index number into each item of the list, + | and is called just before saving out the list. This is so when we + | read them in we can reference pointer links. In their normal state + | these data structures are cross referenced via pointers, but once + | saved/restored the pointers have no meaning, so we use the index to + | re-reference the pointers to the correct data items when they are + | read back in. + | + +-------------------------------------------------------------------------+*/ +void SServListIndex() { + SOURCE_SERVER_BUFFER *ServList; + USHORT Count = 0; + + ServList = SServListStart; + while (ServList) { + ServList->Index = Count++; + ServList = ServList->next; + } + +} // SServListIndex + + +/*+-------------------------------------------------------------------------+ + | SServListIndexMapGet() + | + +-------------------------------------------------------------------------+*/ +void SServListIndexMapGet(DWORD **pMap) { + DWORD *Map = NULL; + SOURCE_SERVER_BUFFER *ServList; + + Map = AllocMemory(NumSServs * sizeof(DWORD)); + + *pMap = Map; + if (Map == NULL) + return; + + ServList = SServListStart; + while (ServList) { + Map[ServList->Index] = (DWORD) ServList; + ServList = ServList->next; + } + +} // SServListIndexMapGet + + +/*+-------------------------------------------------------------------------+ + | SServListFixup() + | + +-------------------------------------------------------------------------+*/ +void SServListFixup() { + + // There is nothing to fixup in the source server list right now - the + // share list is done later... + +} // SServListFixup + + +/*+-------------------------------------------------------------------------+ + | SServListSave() + | + +-------------------------------------------------------------------------+*/ +void SServListSave(HANDLE hFile) { + DWORD wrote; + ULONG Size; + SOURCE_SERVER_BUFFER *ServList; + + ServList = SServListStart; + + while (ServList) { + Size = (lstrlen(ServList->Name) + 3) * sizeof(TCHAR); + Size += sizeof(SOURCE_SERVER_BUFFER); + WriteFile(hFile, &Size, sizeof(Size), &wrote, NULL); + WriteFile(hFile, ServList, Size, &wrote, NULL); + + // Now save out linked information + ShareListSave(hFile, ServList->ShareList); + + ServList = ServList->next; + } + +} // SServListSave + + +/*+-------------------------------------------------------------------------+ + | SServListLoad() + | + +-------------------------------------------------------------------------+*/ +void SServListLoad(HANDLE hFile) { + BOOL Continue = TRUE; + ULONG Size; + SOURCE_SERVER_BUFFER *tmpPtr; + DWORD wrote; + + while (Continue) { + // Get how long this record is + ReadFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + tmpPtr = AllocMemory(Size); + if (tmpPtr == NULL) + return; + + // Read in the record + ReadFile(hFile, tmpPtr, Size, &wrote, NULL); + + // See if there are more records + if (tmpPtr->next == NULL) + Continue = FALSE; + + // clear out the old links - and fixup new ones + tmpPtr->next = NULL; + tmpPtr->prev = NULL; + + tmpPtr->LName = (LPTSTR) ((BYTE *) tmpPtr + sizeof(SOURCE_SERVER_BUFFER)); + tmpPtr->Name = tmpPtr->LName + 2; + + // link it into the list + if (!SServListStart) + SServListStart = SServListEnd = tmpPtr; + else { + SServListEnd->next = tmpPtr; + tmpPtr->prev = SServListEnd; + SServListEnd = tmpPtr; + } + +#ifdef DEBUG +dprintf(TEXT("\n")); +dprintf(TEXT(" Name: %s\n"), tmpPtr->Name); +dprintf(TEXT(" Version: %u.%u\n\n"), (UINT) tmpPtr->VerMaj, (UINT) tmpPtr->VerMin); +#endif + + // Now load in linked information + if (tmpPtr->ShareList != NULL) { + tmpPtr->ShareList = NULL; + ShareListLoad(hFile, &tmpPtr->ShareList); + } + + NumSServs++; + } + +} // SServListLoad + + + +/*+-------------------------------------------------------------------------+ + | Routines for Destination Server List | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | DServListAdd() + | + +-------------------------------------------------------------------------+*/ +DEST_SERVER_BUFFER *DServListAdd(LPTSTR ServerName) { + DEST_SERVER_BUFFER *tmpPtr; + ULONG Size, strlen1; + + strlen1 = (lstrlen(ServerName) + 3) * sizeof(TCHAR); + Size = sizeof(DEST_SERVER_BUFFER) + strlen1; + tmpPtr = AllocMemory(Size); + + if (tmpPtr != NULL) { + // init it to NULL's + memset(tmpPtr, 0, Size); + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DEST_SERVER_BUFFER)); + tmpPtr->LName = tmpPtr->Name; + lstrcpy(tmpPtr->Name, TEXT("\\\\")); + tmpPtr->Name += 2; + lstrcpy(tmpPtr->Name, ServerName); + + // link it into the list + if (!DServListStart) + DServListStart = DServListEnd = tmpPtr; + else { + DServListEnd->next = tmpPtr; + tmpPtr->prev = DServListEnd; + DServListEnd = tmpPtr; + } + + NumDServs++; + } + + return (tmpPtr); + +} // DServListAdd + + +/*+-------------------------------------------------------------------------+ + | DServListDelete() + | + +-------------------------------------------------------------------------+*/ +void DServListDelete(DEST_SERVER_BUFFER *tmpPtr) { + DEST_SERVER_BUFFER *PrevPtr; + DEST_SERVER_BUFFER *NextPtr; + + if (tmpPtr == NULL) + return; + + if (tmpPtr->UseCount) { + // Decrement use count, only delete if actually gone. + tmpPtr->UseCount--; + if (tmpPtr->UseCount) + return; + } + + // Delete any attached share list first + ShareListDelete(tmpPtr->ShareList); + + // ...and virtual share list + VShareListDeleteAll(tmpPtr); + + // ...and any drive list + if (tmpPtr->DriveList) + FreeMemory(tmpPtr->DriveList); + + // ... domain as well + DomainListDelete(tmpPtr->Domain); + + // -- don't free for user convenience, we will clean up at end, otherwise + // user must enter in password if delete/add + // Free any admin share we made + // NTUseDel(tmpPtr->Name); + + // Now unlink the actual server record + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (DServListEnd == tmpPtr) + DServListEnd = PrevPtr; + + // Check if at start of list + if (DServListStart == tmpPtr) + DServListStart = NextPtr; + + FreeMemory(tmpPtr); + NumDServs--; + + if (!NumDServs) + DServListStart = DServListEnd = NULL; + +} // DServListDelete + + +/*+-------------------------------------------------------------------------+ + | DServListDeleteAll() + | + +-------------------------------------------------------------------------+*/ +void DServListDeleteAll() { + DEST_SERVER_BUFFER *ServList; + DEST_SERVER_BUFFER *ServListNext; + + // Now remove the entries from the internal list + ServList = DServListStart; + + while (ServList) { + ServListNext = ServList->next; + ServList->UseCount = 0; + DServListDelete(ServList); + ServList = ServListNext; + } + +} // DServListDeleteAll + + +/*+-------------------------------------------------------------------------+ + | DServListFind() + | + +-------------------------------------------------------------------------+*/ +DEST_SERVER_BUFFER *DServListFind(LPTSTR ServerName) { + BOOL Found = FALSE; + DEST_SERVER_BUFFER *ServList; + + ServList = DServListStart; + + while ((ServList && !Found)) { + if (!lstrcmpi(ServList->Name, ServerName)) + Found = TRUE; + else + ServList = ServList->next; + } + + if (!Found) + ServList = NULL; + + return (ServList); + +} // DServListFind + + +/*+-------------------------------------------------------------------------+ + | DServListIndex() + | + +-------------------------------------------------------------------------+*/ +void DServListIndex() { + DEST_SERVER_BUFFER *ServList; + USHORT Count = 0; + + ServList = DServListStart; + while (ServList) { + ServList->Index = Count++; + + // Now index the virtual shares for this server + VShareListIndex(ServList); + ServList = ServList->next; + } + +} // DServListIndex + + +/*+-------------------------------------------------------------------------+ + | DServListIndexMapGet() + | + +-------------------------------------------------------------------------+*/ +void DServListIndexMapGet(DWORD **pMap) { + DWORD *Map = NULL; + DEST_SERVER_BUFFER *ServList; + + Map = AllocMemory(NumDServs * sizeof(DWORD)); + + *pMap = Map; + if (Map == NULL) + return; + + ServList = DServListStart; + while (ServList) { + Map[ServList->Index] = (DWORD) ServList; + ServList = ServList->next; + } + +} // DServListIndexMapGet + + +/*+-------------------------------------------------------------------------+ + | DServListFixup() + | + +-------------------------------------------------------------------------+*/ +void DServListFixup() { + DEST_SERVER_BUFFER *ServList; + DWORD *DMap = NULL; + + DomainListIndexMapGet(&DMap); + + if (DMap == NULL) + return; + + // Just need to fixup the domain list pointers + ServList = DServListStart; + while (ServList) { + + if (ServList->Domain != NULL) + ServList->Domain = (DOMAIN_BUFFER *) DMap[(DWORD) ServList->Domain - 1]; + + ServList = ServList->next; + } + + FreeMemory(DMap); + +} // DServListFixup + + +/*+-------------------------------------------------------------------------+ + | DServListSave() + | + +-------------------------------------------------------------------------+*/ +void DServListSave(HANDLE hFile) { + DWORD wrote; + ULONG Size; + DEST_SERVER_BUFFER *ServList; + DOMAIN_BUFFER *db; + + ServList = DServListStart; + + while (ServList) { + Size = (lstrlen(ServList->Name) + 3) * sizeof(TCHAR); + Size += sizeof(DEST_SERVER_BUFFER); + WriteFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + // Need to de-reference the domain pointers to their index, and after + // saving restore them. + db = ServList->Domain; + if (ServList->Domain != NULL) + ServList->Domain = (DOMAIN_BUFFER *) (ServList->Domain->Index + 1); + + WriteFile(hFile, ServList, Size, &wrote, NULL); + ServList->Domain = db; + + // Now save out linked information + ShareListSave(hFile, ServList->ShareList); + VShareListSave(hFile, ServList); + + ServList = ServList->next; + } + +} // DServListSave + + +/*+-------------------------------------------------------------------------+ + | DServListLoad() + | + +-------------------------------------------------------------------------+*/ +void DServListLoad(HANDLE hFile) { + BOOL Continue = TRUE; + ULONG Size; + DEST_SERVER_BUFFER *tmpPtr; + DWORD wrote; + + while (Continue) { + // Get how long this record is + ReadFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + tmpPtr = AllocMemory(Size); + if (tmpPtr == NULL) + return; + + // Read in the record + ReadFile(hFile, tmpPtr, Size, &wrote, NULL); + + // See if there are more records + if (tmpPtr->next == NULL) + Continue = FALSE; + + // clear out the old links - and fixup new ones + tmpPtr->next = NULL; + tmpPtr->prev = NULL; + + tmpPtr->LName = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DEST_SERVER_BUFFER)); + tmpPtr->Name = tmpPtr->LName + 2; + + // link it into the list + if (!DServListStart) + DServListStart = DServListEnd = tmpPtr; + else { + DServListEnd->next = tmpPtr; + tmpPtr->prev = DServListEnd; + DServListEnd = tmpPtr; + } + + // The drive list is no longer valid - so clear it out. + tmpPtr->DriveList = NULL; + +#ifdef DEBUG +dprintf(TEXT("\n")); +dprintf(TEXT(" Name: %s\n"), tmpPtr->Name); +dprintf(TEXT(" Version: %u.%u\n\n"), (UINT) tmpPtr->VerMaj, (UINT) tmpPtr->VerMin); +#endif + + // Now load in linked information + if (tmpPtr->ShareList != NULL) { + tmpPtr->ShareList = NULL; + ShareListLoad(hFile, &tmpPtr->ShareList); + } + + if (tmpPtr->VShareStart != NULL) { + tmpPtr->NumVShares = 0; + tmpPtr->VShareStart = tmpPtr->VShareEnd = NULL; + VShareListLoad(hFile, tmpPtr); + } + + NumDServs++; + } + +} // DServListLoad + + +/*+-------------------------------------------------------------------------+ + | DServListSpaceFree() + | + +-------------------------------------------------------------------------+*/ +void DServListSpaceFree() { + DEST_SERVER_BUFFER *ServList; + DRIVE_BUFFER *Drive; + DRIVE_LIST *DList; + ULONG i; + + ServList = DServListStart; + while (ServList) { + DList = ServList->DriveList; + + if (DList != NULL) { + Drive = DList->DList; + for (i = 0; i < DList->Count; i++) + Drive[i].AllocSpace = 0; + } + + ServList = ServList->next; + } + +} // DServListSpaceFree + + + +/*+-------------------------------------------------------------------------+ + | Routines for Virtual Share Lists | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | VShareListAdd() + | + +-------------------------------------------------------------------------+*/ +VIRTUAL_SHARE_BUFFER *VShareListAdd(DEST_SERVER_BUFFER *DServ, LPTSTR ShareName, LPTSTR Path) { + VIRTUAL_SHARE_BUFFER *tmpPtr; + ULONG Size, strlen1; + + // base struct + both strings and 2 ending NULL's + strlen1 = ((lstrlen(ShareName)+ 1) * sizeof(TCHAR)); + Size = sizeof(VIRTUAL_SHARE_BUFFER) + strlen1; + tmpPtr = AllocMemory(Size); + + if (tmpPtr != NULL) { + // init it to NULL's + memset(tmpPtr, 0, Size); + tmpPtr->VFlag = TRUE; + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(VIRTUAL_SHARE_BUFFER)); + lstrcpy(tmpPtr->Name, ShareName); + lstrcpy(tmpPtr->Path, Path); + + // link it into the list + if (!DServ->VShareStart) + DServ->VShareStart = DServ->VShareEnd = tmpPtr; + else { + DServ->VShareEnd->next = tmpPtr; + tmpPtr->prev = DServ->VShareEnd; + DServ->VShareEnd = tmpPtr; + } + + DServ->NumVShares++; + } + + return (tmpPtr); + +} // VShareListAdd + + +/*+-------------------------------------------------------------------------+ + | VShareListDelete() + | + +-------------------------------------------------------------------------+*/ +void VShareListDelete(DEST_SERVER_BUFFER *DServ, VIRTUAL_SHARE_BUFFER *tmpPtr) { + VIRTUAL_SHARE_BUFFER *PrevPtr; + VIRTUAL_SHARE_BUFFER *NextPtr; + + if (tmpPtr == NULL) + return; + + if (tmpPtr->UseCount) { + // Decrement use count, only delete if actually gone. + tmpPtr->UseCount--; + if (tmpPtr->UseCount > 0) + return; + } + + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (DServ->VShareEnd == tmpPtr) + DServ->VShareEnd = PrevPtr; + + // Check if at start of list + if (DServ->VShareStart == tmpPtr) + DServ->VShareStart = NextPtr; + + FreeMemory(tmpPtr); + DServ->NumVShares--; + + if (!DServ->NumVShares) + DServ->VShareStart = DServ->VShareEnd = NULL; + +} // VShareListDelete + + +/*+-------------------------------------------------------------------------+ + | VShareListDeleteAll() + | + +-------------------------------------------------------------------------+*/ +void VShareListDeleteAll(DEST_SERVER_BUFFER *DServ) { + VIRTUAL_SHARE_BUFFER *ShareList; + VIRTUAL_SHARE_BUFFER *ShareListNext; + + // Now remove the entries from the internal list + ShareList = DServ->VShareStart; + + while (ShareList) { + ShareListNext = ShareList->next; + + // Flag to zero to make sure destroyed + ShareList->UseCount = 0; + VShareListDelete(DServ, ShareList); + ShareList = ShareListNext; + } + +} // VShareListDeleteAll + + +/*+-------------------------------------------------------------------------+ + | VShareListIndex() + | + +-------------------------------------------------------------------------+*/ +void VShareListIndex(DEST_SERVER_BUFFER *DServ) { + VIRTUAL_SHARE_BUFFER *ShareList; + USHORT Count = 0; + + ShareList = DServ->VShareStart; + while (ShareList) { + ShareList->Index = Count++; + ShareList = ShareList->next; + } + +} // VShareListIndex + + +/*+-------------------------------------------------------------------------+ + | VShareListIndexMapGet() + | + +-------------------------------------------------------------------------+*/ +void VShareListIndexMapGet(DEST_SERVER_BUFFER *DServ, DWORD **pMap) { + DWORD *Map = NULL; + VIRTUAL_SHARE_BUFFER *ShareList; + + Map = AllocMemory( DServ->NumVShares * sizeof(DWORD) ); + + *pMap = Map; + if (Map == NULL) + return; + + ShareList = DServ->VShareStart; + while (ShareList) { + Map[ShareList->Index] = (DWORD) ShareList; + ShareList = ShareList->next; + } + +} // VShareListIndexMapGet + + +/*+-------------------------------------------------------------------------+ + | VShareListSave() + | + +-------------------------------------------------------------------------+*/ +void VShareListSave(HANDLE hFile, DEST_SERVER_BUFFER *DServ) { + DWORD wrote; + ULONG Size; + VIRTUAL_SHARE_BUFFER *ShareList; + + ShareList = DServ->VShareStart; + + while (ShareList) { + Size = (lstrlen(ShareList->Name) + 1) * sizeof(TCHAR); + Size += sizeof(VIRTUAL_SHARE_BUFFER); + WriteFile(hFile, &Size, sizeof(Size), &wrote, NULL); + WriteFile(hFile, ShareList, Size, &wrote, NULL); + ShareList = ShareList->next; + } + +} // VShareListSave + + +/*+-------------------------------------------------------------------------+ + | VShareListLoad() + | + +-------------------------------------------------------------------------+*/ +void VShareListLoad(HANDLE hFile, DEST_SERVER_BUFFER *DServ) { + BOOL Continue = TRUE; + ULONG Size; + VIRTUAL_SHARE_BUFFER *tmpPtr; + DWORD wrote; + + while (Continue) { + // Get how long this record is + ReadFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + tmpPtr = AllocMemory(Size); + if (tmpPtr == NULL) + return; + + // Read in the record + ReadFile(hFile, tmpPtr, Size, &wrote, NULL); + + // See if there are more records + if (tmpPtr->next == NULL) + Continue = FALSE; + + // clear out the old links - and fixup new ones + tmpPtr->next = NULL; + tmpPtr->prev = NULL; + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(VIRTUAL_SHARE_BUFFER)); + tmpPtr->Drive = NULL; + + // link it into the list + if (!DServ->VShareStart) + DServ->VShareStart = DServ->VShareEnd = tmpPtr; + else { + DServ->VShareEnd->next = tmpPtr; + tmpPtr->prev = DServ->VShareEnd; + DServ->VShareEnd = tmpPtr; + } + + DServ->NumVShares++; + } + +} // VShareListLoad + + +/*+-------------------------------------------------------------------------+ + | VShareListFixup() + | + +-------------------------------------------------------------------------+*/ +void VShareListFixup(DEST_SERVER_BUFFER *DServ) { + VIRTUAL_SHARE_BUFFER *VShare; + USHORT Count = 0; + DWORD di; + DRIVE_LIST *Drives; + DRIVE_BUFFER *DList; + ULONG TotalDrives; + TCHAR Drive[2]; + + if (DServ->DriveList == NULL) + return; + + TotalDrives = 0; + Drives = DServ->DriveList; + Drive[1] = TEXT('\0'); + DList = Drives->DList; + TotalDrives = Drives->Count; + + VShare = DServ->VShareStart; + while (VShare) { + VShare->Drive = NULL; + + // Scan drive list looking for match to share path + for (di = 0; di < TotalDrives; di++) { + // Get first char from path - should be drive letter + Drive[0] = *VShare->Path; + if (!lstrcmpi(Drive, DList[di].Drive)) + VShare->Drive = &DList[di]; + } + + VShare = VShare->next; + } + +} // VShareListFixup + + + +/*+-------------------------------------------------------------------------+ + | Routines for Domain Lists | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | DomainListAdd() + | + +-------------------------------------------------------------------------+*/ +DOMAIN_BUFFER *DomainListAdd(LPTSTR DomainName, LPTSTR PDCName) { + DOMAIN_BUFFER *tmpPtr; + ULONG Size, strlen1, strlen2; + + // base struct + both strings and 2 ending NULL's + strlen1 = ((lstrlen(DomainName) + 1) * sizeof(TCHAR)); + strlen2 = ((lstrlen(PDCName) + 1) * sizeof(TCHAR)); + Size = sizeof(DOMAIN_BUFFER) + strlen1 + strlen2; + tmpPtr = AllocMemory(Size); + + if (tmpPtr != NULL) { + // init it to NULL's + memset(tmpPtr, 0, Size); + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DOMAIN_BUFFER)); + tmpPtr->PDCName = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DOMAIN_BUFFER) + strlen1); + lstrcpy(tmpPtr->Name, DomainName); + lstrcpy(tmpPtr->PDCName, PDCName); + + // link it into the list + if (!DomainListStart) + DomainListStart = DomainListEnd = tmpPtr; + else { + DomainListEnd->next = tmpPtr; + tmpPtr->prev = DomainListEnd; + DomainListEnd = tmpPtr; + } + + NumDomains++; + } + + return (tmpPtr); + +} // DomainListAdd + + +/*+-------------------------------------------------------------------------+ + | DomainListDelete() + | + +-------------------------------------------------------------------------+*/ +void DomainListDelete(DOMAIN_BUFFER *tmpPtr) { + DOMAIN_BUFFER *PrevPtr; + DOMAIN_BUFFER *NextPtr; + + if (tmpPtr == NULL) + return; + + if (tmpPtr->UseCount) { + // Decrement use count, only delete if actually gone. + tmpPtr->UseCount--; + if (tmpPtr->UseCount) + return; + } + + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (DomainListEnd == tmpPtr) + DomainListEnd = PrevPtr; + + // Check if at start of list + if (DomainListStart == tmpPtr) + DomainListStart = NextPtr; + + FreeMemory(tmpPtr); + NumDomains--; + + if (!NumDomains) + DomainListStart = DomainListEnd = NULL; + +} // DomainListDelete + + +/*+-------------------------------------------------------------------------+ + | DomainListDeleteAll() + | + +-------------------------------------------------------------------------+*/ +void DomainListDeleteAll() { + DOMAIN_BUFFER *DomList; + DOMAIN_BUFFER *DomListNext; + + // Now remove the entries from the internal list + DomList = DomainListStart; + + while (DomList) { + DomListNext = DomList->next; + DomList->UseCount = 0; + DomainListDelete(DomList); + DomList = DomListNext; + } + +} // DomainListDeleteAll + + +/*+-------------------------------------------------------------------------+ + | DomainListFind() + | + +-------------------------------------------------------------------------+*/ +DOMAIN_BUFFER *DomainListFind(LPTSTR DomainName) { + BOOL Found = FALSE; + DOMAIN_BUFFER *DomainList; + + DomainList = DomainListStart; + + while ((DomainList && !Found)) { + if (!lstrcmpi(DomainList->Name, DomainName)) + Found = TRUE; + else + DomainList = DomainList->next; + } + + if (!Found) + DomainList = NULL; + + return (DomainList); + +} // DomainListFind + + +/*+-------------------------------------------------------------------------+ + | DomainListIndex() + | + +-------------------------------------------------------------------------+*/ +void DomainListIndex() { + DOMAIN_BUFFER *DomList; + USHORT Count = 0; + + DomList = DomainListStart; + while (DomList) { + DomList->Index = Count++; + DomList = DomList->next; + } + +} // DomainListIndex + + +/*+-------------------------------------------------------------------------+ + | DomainListIndexMapGet() + | + +-------------------------------------------------------------------------+*/ +void DomainListIndexMapGet(DWORD **pMap) { + DWORD *Map = NULL; + DOMAIN_BUFFER *DomList; + + Map = AllocMemory(NumDomains * sizeof(DWORD)); + + *pMap = Map; + if (Map == NULL) + return; + + DomList = DomainListStart; + while (DomList) { + Map[DomList->Index] = (DWORD) DomList; + DomList = DomList->next; + } + +} // DomainListIndexMapGet + + +/*+-------------------------------------------------------------------------+ + | DomainListSave() + | + +-------------------------------------------------------------------------+*/ +void DomainListSave(HANDLE hFile) { + DWORD wrote; + ULONG Size; + DOMAIN_BUFFER *DomList; + + WriteFile(hFile, &NumDomains, sizeof(NumDomains), &wrote, NULL); + + DomList = DomainListStart; + while (DomList) { + Size = (lstrlen(DomList->Name) + 1) * sizeof(TCHAR); + Size += (lstrlen(DomList->PDCName) + 1) * sizeof(TCHAR); + Size += sizeof(DOMAIN_BUFFER); + WriteFile(hFile, &Size, sizeof(Size), &wrote, NULL); + WriteFile(hFile, DomList, Size, &wrote, NULL); + DomList = DomList->next; + } + +} // DomainListSave + + +/*+-------------------------------------------------------------------------+ + | DomainListLoad() + | + +-------------------------------------------------------------------------+*/ +void DomainListLoad(HANDLE hFile) { + BOOL Continue = TRUE; + ULONG Size, namelen; + DOMAIN_BUFFER *tmpPtr; + DWORD wrote; + + ReadFile(hFile, &NumDomains, sizeof(NumDomains), &wrote, NULL); + if (NumDomains == 0) + Continue = FALSE; + + NumDomains = 0; + while (Continue) { + // Get how long this record is + ReadFile(hFile, &Size, sizeof(Size), &wrote, NULL); + + tmpPtr = AllocMemory(Size); + if (tmpPtr == NULL) + return; + + // Read in the record + ReadFile(hFile, tmpPtr, Size, &wrote, NULL); + + // See if there are more records + if (tmpPtr->next == NULL) + Continue = FALSE; + + // clear out the old links - and fixup new ones + tmpPtr->next = NULL; + tmpPtr->prev = NULL; + tmpPtr->Name = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DOMAIN_BUFFER)); + namelen = ((lstrlen(tmpPtr->Name) + 1) * sizeof(TCHAR)); + tmpPtr->PDCName = (LPTSTR) ((BYTE *) tmpPtr + sizeof(DOMAIN_BUFFER) + namelen); + +#ifdef DEBUG +dprintf(TEXT("\n")); +dprintf(TEXT(" Name: %s\n"), tmpPtr->Name); +dprintf(TEXT(" PDC Name: %s\n\n"), tmpPtr->PDCName); +#endif + + // link it into the list + if (!DomainListStart) + DomainListStart = DomainListEnd = tmpPtr; + else { + DomainListEnd->next = tmpPtr; + tmpPtr->prev = DomainListEnd; + DomainListEnd = tmpPtr; + } + + NumDomains++; + } + +} // DomainListLoad + + + +/*+-------------------------------------------------------------------------+ + | Routines for Convert Lists | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ConvertListAdd() + | + | Allocates and inserts a new record for holding a server pair and + | associated conversion options. + | + | Comments: + | The convert list is a doubly linked list of records. Each record + | contains the source and destination server (server-pair) and a + | pointer to the conversion specific information. The exact info + | is specific to the platform being converted from (source server type) + | + +-------------------------------------------------------------------------+*/ +CONVERT_LIST *ConvertListAdd(SOURCE_SERVER_BUFFER *SourceServer, DEST_SERVER_BUFFER *DestServer) { + CONVERT_OPTIONS *cvo; + CONVERT_LIST *tmpPtr; + CONVERT_LIST *cPtr; + BOOL match = FALSE; + + tmpPtr = AllocMemory(sizeof(CONVERT_LIST)); + + if (tmpPtr != NULL) { + // zero it out + memset(tmpPtr, 0, sizeof(CONVERT_LIST)); + + tmpPtr->SourceServ = SourceServer; + tmpPtr->FileServ = DestServer; + + // initialize the conversion options + UserOptionsInit(&tmpPtr->ConvertOptions); + + // Set NetWareInfo based on current FPNW setting... + cvo = (CONVERT_OPTIONS *) tmpPtr->ConvertOptions; + cvo->NetWareInfo = DestServer->IsFPNW; + + FileOptionsInit(&tmpPtr->FileOptions); + + // link it into the list - we want to link right after another + // convert to this same server, or to the same domain. otherwise + // tag it onto the end of the list. + if (!ConvertListStart) + ConvertListStart = ConvertListEnd = tmpPtr; + else { + // Have some files in the list - find out if destination server + // is already in the list and if so append after it. + if (DestServer->UseCount > 1) { + // should be in the list so find it. + cPtr = ConvertListStart; + while (cPtr && !match) { + if (!lstrcmpi(DestServer->Name, cPtr->FileServ->Name)) + match = TRUE; + else + cPtr = cPtr->next; + } + + if (match) { + // have a match - so go to the end of the matching pairs... + while (cPtr && match) { + if (lstrcmpi(DestServer->Name, cPtr->FileServ->Name)) + match = FALSE; + else + cPtr = cPtr->next; + } + + match = !match; + } + } + + // if didn't find a server match - look for a domain match + if (!match) { + if (DestServer->InDomain && DestServer->Domain) { + // should be in the list so find it. + cPtr = ConvertListStart; + while (cPtr && !match) { + if (cPtr->FileServ->InDomain && cPtr->FileServ->Domain) + if (!lstrcmpi(DestServer->Domain->Name, cPtr->FileServ->Domain->Name)) + match = TRUE; + + if (!match) + cPtr = cPtr->next; + } + + if (match) { + // have a match - so go to the end of the matching pairs... + while (cPtr && match) { + if (cPtr->FileServ->InDomain && cPtr->FileServ->Domain) { + if (lstrcmpi(DestServer->Domain->Name, cPtr->FileServ->Domain->Name)) + match = FALSE; + } else + match = FALSE; + + if (match) + cPtr = cPtr->next; + } + + match = !match; + } + } + } + + // if match then in middle of buffer, else use end + if (match && (cPtr != ConvertListEnd)) { + tmpPtr->prev = cPtr->prev; + tmpPtr->next = cPtr; + cPtr->prev->next = tmpPtr; + } else { + // only one in list so add at end + ConvertListEnd->next = tmpPtr; + tmpPtr->prev = ConvertListEnd; + ConvertListEnd = tmpPtr; + } + + } + + NumServerPairs++; + } + + return (tmpPtr); + +} // ConvertListAdd + + +/*+-------------------------------------------------------------------------+ + | ConvertListDelete() + | + | Removes and deallocates a convert list entry from the conversion + | list. + | + +-------------------------------------------------------------------------+*/ +void ConvertListDelete(CONVERT_LIST *tmpPtr) { + CONVERT_LIST *PrevPtr; + CONVERT_LIST *NextPtr; + + // First get rid of the source and destination server this is pointing to - + // those routines take care of freeing up chained data structures. Also + // DServList will only be delete if it's UseCount goes to 0. + SServListDelete(tmpPtr->SourceServ); + DServListDelete(tmpPtr->FileServ); + + // Now unlink the actual convert list record + PrevPtr = tmpPtr->prev; + NextPtr = tmpPtr->next; + + if (PrevPtr) + PrevPtr->next = NextPtr; + + if (NextPtr) + NextPtr->prev = PrevPtr; + + // Check if at end of list + if (ConvertListEnd == tmpPtr) + ConvertListEnd = PrevPtr; + + // Check if at start of list + if (ConvertListStart == tmpPtr) + ConvertListStart = NextPtr; + + FreeMemory(tmpPtr->ConvertOptions); + FreeMemory(tmpPtr); + NumServerPairs--; + + if (!NumServerPairs) + ConvertListStart = ConvertListEnd = NULL; + +} // ConvertListDelete + + +/*+-------------------------------------------------------------------------+ + | ConvertListDeleteAll() + | + | Removes and deallocates all the convert list entrys and removes them + | from the listbox. + | + +-------------------------------------------------------------------------+*/ +void ConvertListDeleteAll() { + CONVERT_LIST *ConvList; + CONVERT_LIST *ConvListNext; + + // Now remove the entries from the internal list + ConvList = ConvertListStart; + + while (ConvList) { + ConvListNext = ConvList->next; + ConvertListDelete(ConvList); + ConvList = ConvListNext; + } + +} // ConvertListDeleteAll + + +/*+-------------------------------------------------------------------------+ + | ConvertListSaveAll() + | + +-------------------------------------------------------------------------+*/ +void ConvertListSaveAll(HANDLE hFile) { + DWORD wrote; + SOURCE_SERVER_BUFFER *ss; + DEST_SERVER_BUFFER *ds; + + // First need to walk source and dest server lists and re-synch the + // index numbers as we can't use pointers loading them back in. + SServListIndex(); + DServListIndex(); // Takes care of the VShares + DomainListIndex(); + + // Done with re-synch of indexes - do actual saving. + CurrentConvertList = ConvertListStart; + while (CurrentConvertList) { + // Need to de-reference the server pointers to their index, and after + // saving restore them. + ss = CurrentConvertList->SourceServ; + ds = CurrentConvertList->FileServ; + CurrentConvertList->SourceServ = (SOURCE_SERVER_BUFFER *) CurrentConvertList->SourceServ->Index; + CurrentConvertList->FileServ = (DEST_SERVER_BUFFER *) CurrentConvertList->FileServ->Index; + + WriteFile(hFile, CurrentConvertList, sizeof(CONVERT_LIST), &wrote, NULL); + + CurrentConvertList->SourceServ = ss; + CurrentConvertList->FileServ = ds; + + // Now the options + UserOptionsSave(hFile, CurrentConvertList->ConvertOptions); + FileOptionsSave(hFile, CurrentConvertList->FileOptions); + + CurrentConvertList = CurrentConvertList->next; + } + + // Saved out the convert list - now need to save out the linked + // information (these routines save their linked info as well). + DomainListSave(hFile); + DServListSave(hFile); + SServListSave(hFile); + +} // ConvertListSaveAll + + +/*+-------------------------------------------------------------------------+ + | ConvertListLoadAll() + | + +-------------------------------------------------------------------------+*/ +void ConvertListLoadAll(HANDLE hFile) { + CONVERT_LIST *tmpPtr; + BOOL Continue = TRUE; + DWORD wrote; + + while (Continue) { + tmpPtr = AllocMemory(sizeof(CONVERT_LIST)); + if (tmpPtr == NULL) + return; + + // Read in the record + ReadFile(hFile, tmpPtr, sizeof(CONVERT_LIST), &wrote, NULL); + + // See if there are more records + if (tmpPtr->next == NULL) + Continue = FALSE; + + // clear out the old links - and fixup new ones + tmpPtr->next = NULL; + tmpPtr->prev = NULL; + tmpPtr->ConvertOptions = NULL; + tmpPtr->FileOptions = NULL; + + // Read in options - note the trusted domain must be fixed up later + // after the domain list is read in + UserOptionsLoad(hFile, &tmpPtr->ConvertOptions); + FileOptionsLoad(hFile, &tmpPtr->FileOptions); + + // link it into the list + if (!ConvertListStart) + ConvertListStart = ConvertListEnd = tmpPtr; + else { + ConvertListEnd->next = tmpPtr; + tmpPtr->prev = ConvertListEnd; + ConvertListEnd = tmpPtr; + } + + NumServerPairs++; + } + + // Loaded the convert list - now need to bring in the linked + // information (these routines load their linked info as well). + DomainListLoad(hFile); + DServListLoad(hFile); + SServListLoad(hFile); + +} // ConvertListLoadAll + + +/*+-------------------------------------------------------------------------+ + | ConvertListFixup() + | + +-------------------------------------------------------------------------+*/ +void ConvertListFixup(HWND hWnd) { + BOOL ok = TRUE; + DWORD *SMap = NULL; + DWORD *DMap = NULL; + CONVERT_LIST *NextList; + CONVERT_OPTIONS *cvto; + + // Generate Source and Destination server Index -> pointer maps + DServListIndexMapGet(&DMap); + SServListIndexMapGet(&SMap); + + if ((DMap == NULL) || (SMap == NULL)) + return; + + CurrentConvertList = ConvertListStart; + while (CurrentConvertList) { + CurrentConvertList->FileServ = (DEST_SERVER_BUFFER *) DMap[(DWORD) CurrentConvertList->FileServ]; + CurrentConvertList->SourceServ = (SOURCE_SERVER_BUFFER *) SMap[(DWORD) CurrentConvertList->SourceServ]; + + CurrentConvertList = CurrentConvertList->next; + } + + // Free up the index maps + FreeMemory(DMap); + FreeMemory(SMap); + + // Fixed the convert list - now need to fix the linked information + // (these routines fix-up their linked info as well). + DServListFixup(); + SServListFixup(); + + // For the user options later on + DomainListIndexMapGet(&DMap); + + // Now validate each of the machines + CurrentConvertList = ConvertListStart; + while (CurrentConvertList) { + ok = TRUE; + if (!NTServerValidate(hWnd, CurrentConvertList->FileServ->Name)) + ok = FALSE; + + if (ok) + if (!NWServerValidate(hWnd, CurrentConvertList->SourceServ->Name, FALSE)) + ok = FALSE; + + NextList = CurrentConvertList->next; + + if (!ok) { + ConvertListDelete(CurrentConvertList); + } else { + // The connections were okay to these so resynch their information + NWServerInfoReset(CurrentConvertList->SourceServ); + NTServerInfoReset(hWnd, CurrentConvertList->FileServ, TRUE); + DestShareListFixup(CurrentConvertList->FileServ); + VShareListFixup(CurrentConvertList->FileServ); + SourceShareListFixup(CurrentConvertList->FileServ, CurrentConvertList->SourceServ->ShareList); + + // need to fixup the trusted domain in the user options to the new + // domain list... + cvto = (CONVERT_OPTIONS *) CurrentConvertList->ConvertOptions; + + if (cvto->UseTrustedDomain) + cvto->TrustedDomain = (DOMAIN_BUFFER *) DMap[(DWORD) cvto->TrustedDomain]; + else + cvto->TrustedDomain = NULL; + + } + + CurrentConvertList = NextList; + } + + // Free up the domain index map + FreeMemory(DMap); + +} // ConvertListFixup + + +/*+-------------------------------------------------------------------------+ + | ConvertListLog() + | + +-------------------------------------------------------------------------+*/ +void ConvertListLog() { + DEST_SERVER_BUFFER *DServ = NULL; + SOURCE_SERVER_BUFFER *SServ = NULL; + ULONG i; + + CurrentConvertList = ConvertListStart; + + // Log format is: + // + // Number of Servers = 1 + // + // [Servers] + // From: Source1 To: Dest1 + // From: Source2 To: Dest2 + LogWriteLog(0, Lids(IDS_L_126), NumServerPairs); + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_L_127)); + + LogWriteSummary(0, Lids(IDS_L_126), NumServerPairs); + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteSummary(0, Lids(IDS_L_127)); + + // Loop through the conversion pairs (they are already in order) + while (CurrentConvertList) { + LogWriteLog(1, Lids(IDS_L_128), CurrentConvertList->SourceServ->Name, CurrentConvertList->FileServ->Name); + LogWriteSummary(1, Lids(IDS_L_128), CurrentConvertList->SourceServ->Name, CurrentConvertList->FileServ->Name); + CurrentConvertList = CurrentConvertList->next; + } + + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteSummary(0, Lids(IDS_CRLF)); + + // Now write detailed info on each server + CurrentConvertList = ConvertListStart; + + // header for this section + LogWriteLog(0, Lids(IDS_LINE)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_129)); + LogWriteLog(0, Lids(IDS_LINE)); + LogWriteLog(0, Lids(IDS_CRLF)); + + while (CurrentConvertList) { + // Make sure to only log each source server once + if (DServ != CurrentConvertList->FileServ) { + // remember this new server + DServ = CurrentConvertList->FileServ; + + LogWriteLog(0, TEXT("[%s]\r\n"), CurrentConvertList->FileServ->Name); + LogWriteLog(1, Lids(IDS_L_130)); + LogWriteLog(1, Lids(IDS_L_131), DServ->VerMaj, DServ->VerMin); + + if (DServ->DriveList) { + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(1, Lids(IDS_L_132)); + + for (i = 0; i < DServ->DriveList->Count; i++) { + LogWriteLog(2, TEXT("%s: [%4s] %s\r\n"), DServ->DriveList->DList[i].Drive, DServ->DriveList->DList[i].DriveType, DServ->DriveList->DList[i].Name); + LogWriteLog(3, Lids(IDS_L_133), lToStr(DServ->DriveList->DList[i].FreeSpace)); + } + } + + // Log Shares + ShareListLog(DServ->ShareList, TRUE); + } + + // Now for the source server + SServ = CurrentConvertList->SourceServ; + LogWriteLog(0, TEXT("[%s]\r\n"), CurrentConvertList->SourceServ->Name); + LogWriteLog(1, Lids(IDS_L_134)); + LogWriteLog(1, Lids(IDS_L_135), (UINT) SServ->VerMaj, (UINT) SServ->VerMin); + + ShareListLog(SServ->ShareList, FALSE); + + CurrentConvertList = CurrentConvertList->next; + } + +} // ConvertListLog + + +/*+-------------------------------------------------------------------------+ + | UserServerNameGet() + | + +-------------------------------------------------------------------------+*/ +LPTSTR UserServerNameGet(DEST_SERVER_BUFFER *DServ, void *COpt) { + CONVERT_OPTIONS *ConvOpt; + LPTSTR ServName = NULL; + + ConvOpt = (CONVERT_OPTIONS *) COpt; + // If going to a trusted domain then point to it's PDC for user transfers + if (ConvOpt->UseTrustedDomain && (ConvOpt->TrustedDomain != NULL) && (ConvOpt->TrustedDomain->PDCName != NULL)) { + ServName = ConvOpt->TrustedDomain->PDCName; + } else + // If in a domain then point to the PDC for user transfers + if (DServ->InDomain && DServ->Domain) { + ServName = DServ->Domain->PDCName; + } else { + ServName = DServ->Name; + } + + return ServName; +} // UserServerNameGet diff --git a/private/nw/convert/nwconv/servlist.h b/private/nw/convert/nwconv/servlist.h new file mode 100644 index 000000000..ec4075e91 --- /dev/null +++ b/private/nw/convert/nwconv/servlist.h @@ -0,0 +1,311 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HSERVLIST_ +#define _HSERVLIST_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*+-------------------------------------------------------------------------+ + | User List | + +-------------------------------------------------------------------------+*/ +typedef struct _USER_BUFFER { + TCHAR Name[MAX_USER_NAME_LEN + 1]; + TCHAR NewName[MAX_USER_NAME_LEN + MAX_UCONST_LEN]; + TCHAR Password[MAX_PW_LEN + 1]; + + USHORT err; + BOOL Overwrite; + BOOL IsNewName; +} USER_BUFFER; + +typedef struct _USER_LIST { + ULONG Count; + USER_BUFFER UserBuffer[]; +} USER_LIST; + + +/*+-------------------------------------------------------------------------+ + | Group List | + +-------------------------------------------------------------------------+*/ +typedef struct _GROUP_BUFFER { + TCHAR Name[MAX_GROUP_NAME_LEN + 1]; + TCHAR NewName[MAX_GROUP_NAME_LEN + MAX_UCONST_LEN]; + + USHORT err; + BOOL IsNewName; +} GROUP_BUFFER; + +typedef struct _GROUP_LIST { + ULONG Count; + GROUP_BUFFER GroupBuffer[]; +} GROUP_LIST; + + +/*+-------------------------------------------------------------------------+ + | Drive Lists | + +-------------------------------------------------------------------------+*/ + +// Drive type of 1 is okay to set perms on, all others are not... +#define DRIVE_TYPE_NTFS 1 + +// Drive list is only kept for destination servers and is mainly used to track +// remaining free space on the drive. +typedef struct _DRIVE_BUFFER { + UINT Type; + TCHAR Drive[2]; + TCHAR DriveType[20]; + TCHAR Name[20]; + ULONG TotalSpace; + ULONG FreeSpace; // Free space before stuff we are transfering + ULONG AllocSpace; // Approx size of stuff we are transferring +} DRIVE_BUFFER; + +typedef struct _DRIVE_LIST { + ULONG Count; + DRIVE_BUFFER DList[]; +} DRIVE_LIST; + + +// Stores a server share and a link to the structures describing the files +// to convert +typedef struct _SHARE_BUFFER { + BOOL VFlag; // to distinguish between virtual and normal share + + USHORT Index; + + TCHAR Name[MAX_SHARE_NAME_LEN + 1]; + BOOL Convert; + BOOL HiddenFiles; + BOOL SystemFiles; + BOOL ToFat; // Flag if user says OK to go to a FAT drive + DIR_BUFFER *Root; + DRIVE_BUFFER *Drive; // Used only for dest shares - for free space calcs. + ULONG Size; // Used for source shares - approx allocated space + TCHAR Path[MAX_PATH + 1]; + TCHAR SubDir[MAX_PATH + 1]; // for source - subdir to copy to + + // Following only used for source shares - describes destination share. + // Virtual tells whether data pointed to is a SHARE_BUFFER or + // VIRTUAL_SHARE_BUFFER. (Note: Use struct SHARE_BUFFER even though + // it may be VIRTUAL to simplify logic if it is a SHARE_BUFFER). + BOOL Virtual; + struct _SHARE_BUFFER *DestShare; +} SHARE_BUFFER; + +// List of all server shares and files under them to convert. +typedef struct _SHARE_LIST { + ULONG Count; + ULONG ConvertCount; + BOOL Fixup; + SHARE_BUFFER SList[]; +} SHARE_LIST; + + +// Virtual shares are ones that we need to create - these are only for +// destination shares as all source shares must obviously already exist. +// This must be a linked list as it can be dynamically added to / deleted from. +typedef struct _VIRTUAL_SHARE_BUFFER { + BOOL VFlag; + + struct _VIRTUAL_SHARE_BUFFER *next; + struct _VIRTUAL_SHARE_BUFFER *prev; + + USHORT Index; + + LPTSTR Name; + LONG UseCount; // How many things going to it (so can del if unused) + TCHAR Path[MAX_PATH + 1]; + DRIVE_BUFFER *Drive; +} VIRTUAL_SHARE_BUFFER; + + +// Keep the domain buffers for when servers are part of a domain to point +// to the PDC and also when you choose a trusted domain. It contains an +// abreviated form of a server buffer for the PDC info. +typedef struct _DOMAIN_BUFFER { + struct _DOMAIN_BUFFER *next; + struct _DOMAIN_BUFFER *prev; + + USHORT Index; + + LPTSTR Name; + + // PDC Info + LPTSTR PDCName; + DWORD Type; + DWORD VerMaj; + DWORD VerMin; + LONG UseCount; +} DOMAIN_BUFFER; + + +#define SERV_TYPE_NETWARE 1 +#define SERV_TYPE_NT 2 +/*+-------------------------------------------------------------------------+ + | Server Lists + | + | The source and destination SERVER_BUFFER lists are kept independantly + | of the conversion list as multiple conversions can be done to one server. + | This allows easier tracking of virtual shares that need to be created and + | total free space on the server after all of the conversions are counted in + | (to see if there is enough free space to transfer files). + | + | Source server has no use count as a source server can only be included once + | in a conversion. Also no drive list as we can't get the info (on NetWare + | at least) and it isn't needed. + | + +-------------------------------------------------------------------------+*/ +typedef struct _SOURCE_SERVER_BUFFER { + struct _SOURCE_SERVER_BUFFER *next; + struct _SOURCE_SERVER_BUFFER *prev; + + USHORT Index; + + UINT Type; // Type of server (NetWare only for now) + BYTE VerMaj; + BYTE VerMin; + LPTSTR LName; + LPTSTR Name; + SHARE_LIST *ShareList; +} SOURCE_SERVER_BUFFER; + + +// Destination server must contain useage count as several source servers can +// be merged into it. If UseCount goes to 0, then we can purge this record +// out as it is no longer needed. +typedef struct _DEST_SERVER_BUFFER { + struct _DEST_SERVER_BUFFER *next; + struct _DEST_SERVER_BUFFER *prev; + + USHORT Index; + + DWORD Type; + DWORD VerMaj; + DWORD VerMin; + LPTSTR LName; // Name with double whack pre-pended + LPTSTR Name; + SHARE_LIST *ShareList; + + ULONG NumVShares; + VIRTUAL_SHARE_BUFFER *VShareStart; + VIRTUAL_SHARE_BUFFER *VShareEnd; + ULONG UseCount; + BOOL IsNTAS; + BOOL IsFPNW; + BOOL InDomain; + DOMAIN_BUFFER *Domain; + DRIVE_LIST *DriveList; +} DEST_SERVER_BUFFER; + + +/*+-------------------------------------------------------------------------+ + | Convert List + | + | This is the main data structure that everything links off of. The + | ConvertOptions is a void type to allow it to be based on the type + | of server being converted. This allows the program to be (relatively) + | easily modified to work with other source server types (like + | LAN Server). + | + | The Server list constructs (SOURCE_SERVER_BUFFER and + | DEST_SERVER_BUFFER) are kept in addition to this, but this contains + | some links to those structures. + | + +-------------------------------------------------------------------------+*/ +typedef struct _CONVERT_LIST { + struct _CONVERT_LIST *next; + struct _CONVERT_LIST *prev; + SOURCE_SERVER_BUFFER *SourceServ; + DEST_SERVER_BUFFER *FileServ; + + void *ConvertOptions; + void *FileOptions; +} CONVERT_LIST; + + +/*+-------------------------------------------------------------------------+ + | Function Prototypes | + +-------------------------------------------------------------------------+*/ +void TreeSave(HANDLE hFile, DIR_BUFFER *Dir); +void TreeLoad(HANDLE hFile, DIR_BUFFER **pDir); + +int __cdecl UserListCompare(const void *arg1, const void *arg2); + +void ShareListDelete(SHARE_LIST *ShareList); +void DestShareListFixup(DEST_SERVER_BUFFER *DServ); +void ShareListSave(HANDLE hFile, SHARE_LIST *ShareList); +void ShareListLoad(HANDLE hFile, SHARE_LIST **lpShareList); + +SOURCE_SERVER_BUFFER *SServListAdd(LPTSTR ServerName); +void SServListDelete(SOURCE_SERVER_BUFFER *tmpPtr); +void SServListDeleteAll(); +SOURCE_SERVER_BUFFER *SServListFind(LPTSTR ServerName); +void SServListIndex(); +void SServListIndexMapGet(DWORD **pMap); +void SServListFixup(); +void SServListSave(HANDLE hFile); +void SServListLoad(HANDLE hFile); + +DEST_SERVER_BUFFER *DServListAdd(LPTSTR ServerName); +void DServListDelete(DEST_SERVER_BUFFER *tmpPtr); +void DServListDeleteAll(); +DEST_SERVER_BUFFER *DServListFind(LPTSTR ServerName); +void DServListIndex(); +void DServListIndexMapGet(DWORD **pMap); +void DServListFixup(); +void DServListSave(HANDLE hFile); +void DServListLoad(HANDLE hFile); +void DServListSpaceFree(); + +VIRTUAL_SHARE_BUFFER *VShareListAdd(DEST_SERVER_BUFFER *DServ, LPTSTR ShareName, LPTSTR Path); +void VShareListDelete(DEST_SERVER_BUFFER *DServ, VIRTUAL_SHARE_BUFFER *tmpPtr); +void VShareListDeleteAll(DEST_SERVER_BUFFER *DServ); +void VShareListIndex(DEST_SERVER_BUFFER *DServ) ; +void VShareListIndexMapGet(DEST_SERVER_BUFFER *DServ, DWORD **pMap); +void VShareListSave(HANDLE hFile, DEST_SERVER_BUFFER *DServ); +void VShareListLoad(HANDLE hFile, DEST_SERVER_BUFFER *DServ); + +DOMAIN_BUFFER *DomainListAdd(LPTSTR DomainName, LPTSTR PDCName); +void DomainListDelete(DOMAIN_BUFFER *tmpPtr); +void DomainListDeleteAll(); +DOMAIN_BUFFER *DomainListFind(LPTSTR DomainName); +void DomainListIndex(); +void DomainListIndexMapGet(DWORD **pMap); +void DomainListSave(HANDLE hFile); +void DomainListLoad(HANDLE hFile); + +CONVERT_LIST *ConvertListAdd(SOURCE_SERVER_BUFFER *SourceServer, DEST_SERVER_BUFFER *DestServer); +void ConvertListDelete(CONVERT_LIST *tmpPtr); +void ConvertListDeleteAll(); +void ConvertListSaveAll(HANDLE hFile); +void ConvertListLoadAll(HANDLE hFile); +void ConvertListFixup(HWND hWnd); +void ConvertListLog(); + +LPTSTR UserServerNameGet(DEST_SERVER_BUFFER *DServ, void *ConvOpt); + +// Internal Data Structures +extern UINT NumServerPairs; +extern CONVERT_LIST *ConvertListStart; +extern CONVERT_LIST *ConvertListEnd; +extern CONVERT_LIST ConvertListDefault; +extern CONVERT_LIST *CurrentConvertList; + +extern SOURCE_SERVER_BUFFER *SServListStart; +extern SOURCE_SERVER_BUFFER *SServListEnd; +extern SOURCE_SERVER_BUFFER *SServListCurrent; +extern DEST_SERVER_BUFFER *DServListStart; +extern DEST_SERVER_BUFFER *DServListEnd; +extern DEST_SERVER_BUFFER *DServListCurrent; +extern DOMAIN_BUFFER *DomainListStart; +extern DOMAIN_BUFFER *DomainListEnd; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/sizebarh.cur b/private/nw/convert/nwconv/sizebarh.cur new file mode 100644 index 000000000..dda3483bb Binary files /dev/null and b/private/nw/convert/nwconv/sizebarh.cur differ diff --git a/private/nw/convert/nwconv/sources b/private/nw/convert/nwconv/sources new file mode 100644 index 000000000..c53d61c57 --- /dev/null +++ b/private/nw/convert/nwconv/sources @@ -0,0 +1,56 @@ +TARGETNAME=nwconv +TARGETPATH=obj +TARGETTYPE=PROGRAM + +TARGETLIBS=\ + $(BASEDIR)\public\sdk\lib\*\netapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\ntdll.lib \ + $(BASEDIR)\public\sdk\lib\*\mpr.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\nwapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\samlib.lib + +INCLUDES=\ + $(BASEDIR)\private\nw\inc;\ + $(BASEDIR)\private\inc; + +LINKER_FLAGS=/STACK:0x100000,0x10000 +C_DEFINES=-DWIN32 -DUNICODE -D_UNICODE -DWINVER=0x0400 + +SUBSYSTEM_VERSION=4.00 +MSC_WARNING_LEVEL=/W3 /WX + +SOURCES=\ + NWCONV.RC \ + NWCONV.C \ + ABOUTBOX.C \ + DEBUG.C \ + ERROR.C \ + MEM.C \ + UTILS.C \ + NETUTIL.C \ + TAB.C \ + HIERFILE.C \ + HIERDRAW.C \ + COLUMNLB.C \ + SERVLIST.C \ + NTNETAPI.C \ + NWNETAPI.C \ + SBROWSE.C \ + USERDLG.C \ + FILEDLG.C \ + FILESEL.C \ + NWLOG.C \ + STATBOX.C \ + FCOPY.C \ + FASTCOPY.C \ + TRANSFER.C \ + LOGHOURS.C \ + MAP.C \ + USRPROP.C \ + ENCRYPT.C + +UMTYPE=windows +UMENTRY=winmain + diff --git a/private/nw/convert/nwconv/statbox.c b/private/nw/convert/nwconv/statbox.c new file mode 100644 index 000000000..70d2b42a8 --- /dev/null +++ b/private/nw/convert/nwconv/statbox.c @@ -0,0 +1,568 @@ +/* + +-------------------------------------------------------------------------+ + | Status Dialog box routines - Used during Conversion | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [StatBox.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 08, 1994] | + | Last Update : [Feb 08, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Feb 08, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" +#include "convapi.h" + +static TCHAR tmpStr[1024]; +static TCHAR PanelTitle[80]; +static HANDLE hStatus = NULL; +static HANDLE hPanel = NULL; +static BOOL DoCancel = FALSE; + +/*+-------------------------------------------------------------------------+ + | Routines for status dialog put up during conversion. | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | DrainPump() + +-------------------------------------------------------------------------+*/ +void DrainPump() { + MSG msg; + + while (PeekMessage(&msg, hStatus, 0, 0xfff, PM_REMOVE)) { + if ((IsDialogMessage(hStatus, &msg) == FALSE) && + (IsDialogMessage(hPanel, &msg) == FALSE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + +} // DrainPump + + +/*+-------------------------------------------------------------------------+ + | Status_CurConv() + +-------------------------------------------------------------------------+*/ +// Current server pair being converted +void Status_CurConv(UINT Num) { + wsprintf(tmpStr, TEXT("%5u"), Num); + SendDlgItemMessage(hStatus, IDC_S_CUR_CONV, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_CurConv + + +/*+-------------------------------------------------------------------------+ + | Status_TotConv() + +-------------------------------------------------------------------------+*/ +// Total number of server pairs to convert +void Status_TotConv(UINT Num) { + wsprintf(tmpStr, TEXT("%5u"), Num); + SendDlgItemMessage(hStatus, IDC_S_TOT_CONV, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotConv + + +/*+-------------------------------------------------------------------------+ + | Status_SrcServ() + +-------------------------------------------------------------------------+*/ +// Current source server of server pair being converted +void Status_SrcServ(LPTSTR Server) { + wsprintf(tmpStr, TEXT("%-15s"), Server); + SendDlgItemMessage(hStatus, IDC_S_SRCSERV, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_SrcServ + + +/*+-------------------------------------------------------------------------+ + | Status_DestServ() + +-------------------------------------------------------------------------+*/ +// Current destination server of server pair being converted +void Status_DestServ(LPTSTR Server) { + wsprintf(tmpStr, TEXT("%-15s"), Server); + SendDlgItemMessage(hStatus, IDC_S_DESTSERV, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_DestServ + + +/*+-------------------------------------------------------------------------+ + | Status_ConvTxt() + +-------------------------------------------------------------------------+*/ +// Text describing what is being converted (Groups, Users Files) +void Status_ConvTxt(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%-20s"), Text); + SendDlgItemMessage(hStatus, IDC_S_CONVTXT, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_ConvTxt + + +/*+-------------------------------------------------------------------------+ + | Status_CurNum() + +-------------------------------------------------------------------------+*/ +// Current item number being converted (current group # or User # or file #)... +void Status_CurNum(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_CUR_NUM, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_CurNum + + +/*+-------------------------------------------------------------------------+ + | Status_CurTot() + +-------------------------------------------------------------------------+*/ +// Total items in set being converted (user, group, files...) +void Status_CurTot(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_CUR_TOT, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_CurTot + + +/*+-------------------------------------------------------------------------+ + | Status_ItemLabel() + +-------------------------------------------------------------------------+*/ +// Label for set being converted ("Group:", "User:") +void Status_ItemLabel(LPTSTR Text, ...) { + va_list marker; + + va_start(marker, Text); + + wvsprintf(tmpStr, Text, marker); + SendDlgItemMessage(hStatus, IDC_S_ITEMLABEL, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); + + va_end(marker); + +} // Status_ItemLabel + + +/*+-------------------------------------------------------------------------+ + | Status_Item() + +-------------------------------------------------------------------------+*/ +// Name of current thing being converted (actual user or group name) +void Status_Item(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%-15s"), Text); + SendDlgItemMessage(hStatus, IDC_S_STATUSITEM, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_Item + + +/*+-------------------------------------------------------------------------+ + | Status_TotComplete() + +-------------------------------------------------------------------------+*/ +// Total #server pairs converted so far +void Status_TotComplete(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_TOT_COMP, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotComplete + + +/*+-------------------------------------------------------------------------+ + | Status_TotGroups() + +-------------------------------------------------------------------------+*/ +void Status_TotGroups(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_TOT_GROUPS, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotGroup + + +/*+-------------------------------------------------------------------------+ + | Status_TotUsers() + +-------------------------------------------------------------------------+*/ +void Status_TotUsers(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_TOT_USERS, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotUsers + + +/*+-------------------------------------------------------------------------+ + | Status_TotFiles() + +-------------------------------------------------------------------------+*/ +void Status_TotFiles(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_TOT_FILES, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotFiles + + +/*+-------------------------------------------------------------------------+ + | Status_TotErrors() + +-------------------------------------------------------------------------+*/ +void Status_TotErrors(UINT Num) { + wsprintf(tmpStr, TEXT("%7s"), lToStr(Num)); + SendDlgItemMessage(hStatus, IDC_S_TOT_ERRORS, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotErrors + + +/*+-------------------------------------------------------------------------+ + | Status_BytesTxt() + +-------------------------------------------------------------------------+*/ +void Status_BytesTxt(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%-15s"), Text); + SendDlgItemMessage(hStatus, IDC_PANEL1, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_BytesTxt + + +/*+-------------------------------------------------------------------------+ + | Status_Bytes() + +-------------------------------------------------------------------------+*/ +void Status_Bytes(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%s"), Text); + SendDlgItemMessage(hStatus, IDC_PANEL2, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_Bytes + + +/*+-------------------------------------------------------------------------+ + | Status_TotBytes() + +-------------------------------------------------------------------------+*/ +void Status_TotBytes(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%s"), Text); + SendDlgItemMessage(hStatus, IDC_PANEL3, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_TotBytes + + +/*+-------------------------------------------------------------------------+ + | Status_BytesSep() + +-------------------------------------------------------------------------+*/ +void Status_BytesSep(LPTSTR Text) { + wsprintf(tmpStr, TEXT("%s"), Text); + SendDlgItemMessage(hStatus, IDC_PANEL4, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hStatus, WM_PAINT, 0, 0L); + DrainPump(); +} // Status_BytesSep + + +/*+-------------------------------------------------------------------------+ + | DlgStatus() + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgStatus(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + RECT rc; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + return (TRUE); + + case WM_SETFOCUS: + GetWindowRect(hDlg, &rc); + InvalidateRect(hDlg, &rc, FALSE); + SendMessage(hStatus, WM_PAINT, 0, 0L); + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgStatus + + + +/*+-------------------------------------------------------------------------+ + | DoStatusDlg() + +-------------------------------------------------------------------------+*/ +void DoStatusDlg(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC)DlgStatus, hInst); + hStatus = CreateDialog(hInst, TEXT("StatusDlg"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // DoStatusDlg + + +/*+-------------------------------------------------------------------------+ + | StatusDlgKill() + +-------------------------------------------------------------------------+*/ +void StatusDlgKill() { + DestroyWindow(hStatus); + hStatus = NULL; + +} // StatusDlgKill + + + +/*+-------------------------------------------------------------------------+ + | Information (Panel) Dialog Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | Panel_Line() + +-------------------------------------------------------------------------+*/ +void Panel_Line(int Line, LPTSTR szFormat, ...) { + va_list marker; + + if (hPanel == NULL) + return; + + va_start(marker, szFormat); + + wvsprintf(tmpStr, szFormat, marker); + tmpStr[60] = TEXT('\0'); + SendDlgItemMessage(hPanel, IDC_PANEL1 - 1 + Line, WM_SETTEXT, 0, (LPARAM) tmpStr); + SendMessage(hPanel, WM_PAINT, 0, 0L); + DrainPump(); + + va_end(marker); + +} // Panel_ConvTxt + + +/*+-------------------------------------------------------------------------+ + | Panel_Cancel() + +-------------------------------------------------------------------------+*/ +BOOL Panel_Cancel() { + + if ((hPanel == NULL) || !DoCancel) + return FALSE; + + return TRUE; + +} // Panel_Cancel + + +/*+-------------------------------------------------------------------------+ + | DlgPanel() + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgPanel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + int wmId, wmEvent; + RECT rc; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + DoCancel = FALSE; + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + SendMessage(hDlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) PanelTitle); + return (TRUE); + + case WM_SETFOCUS: + GetWindowRect(hDlg, &rc); + InvalidateRect(hDlg, &rc, FALSE); + SendMessage(hPanel, WM_PAINT, 0, 0L); + break; + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDCANCEL: + DoCancel = TRUE; + return (TRUE); + + break; + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgPanel + + +/*+-------------------------------------------------------------------------+ + | PanelDlg_Do() + +-------------------------------------------------------------------------+*/ +void PanelDlg_Do(HWND hDlg, LPTSTR Title) { + DLGPROC lpfnDlg; + + lstrcpy(PanelTitle, Title); + lpfnDlg = MakeProcInstance((DLGPROC)DlgPanel, hInst); + hPanel = CreateDialog(hInst, TEXT("PanelDLG"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // PanelDlg_Do + + +/*+-------------------------------------------------------------------------+ + | PanelDlgKill() + +-------------------------------------------------------------------------+*/ +void PanelDlgKill() { + + if (hPanel == NULL) + return; + + DestroyWindow(hPanel); + hPanel = NULL; + DoCancel = FALSE; + +} // PanelDlgKill + + +/*+-------------------------------------------------------------------------+ + | Name Error Dialog (User and Group) | + +-------------------------------------------------------------------------+*/ + +static TCHAR OldName[60]; +static TCHAR NewName[60]; +static LPTSTR DlgTitle; +static LPTSTR NameErrorProblem; +static ULONG RetType; +static ULONG MaxNameLen; +/*+-------------------------------------------------------------------------+ + | NameErrorDlg() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK NameErrorDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + int wmId, wmEvent; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // Init all the display fields + SendMessage(hDlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) DlgTitle); + SendMessage(GetDlgItem(hDlg, IDC_OLDNAME), WM_SETTEXT, (WPARAM) 0, (LPARAM) OldName); + SendMessage(GetDlgItem(hDlg, IDC_NEWNAME), WM_SETTEXT, (WPARAM) 0, (LPARAM) NewName); + SendMessage(GetDlgItem(hDlg, IDC_PANEL1), WM_SETTEXT, (WPARAM) 0, (LPARAM) NameErrorProblem); + + // limit the name length + PostMessage(GetDlgItem(hDlg, IDC_NEWNAME), EM_LIMITTEXT, (WPARAM) MaxNameLen, 0); + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDABORT: + // This will cancel the conversion - but need to check with the user + // if this is what they really want to do + if (MessageBox(hDlg, Lids(IDS_E_15), Lids(IDS_E_16), MB_YESNO) == IDYES) { + RetType = (ULONG) IDABORT; + EndDialog(hDlg, 0); + } + + return (TRUE); + break; + + case IDRETRY: + * (WORD *)NewName = (WORD) MaxNameLen + 1; + SendMessage(GetDlgItem(hDlg, IDC_NEWNAME), EM_GETLINE, 0, (LPARAM) NewName); + RetType = (ULONG) IDRETRY; + EndDialog(hDlg, 0); + return (TRUE); + break; + + case IDIGNORE: + RetType = (ULONG) IDCANCEL; + EndDialog(hDlg, 0); + return (TRUE); + break; + + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // NameErrorDlg + + +/*+-------------------------------------------------------------------------+ + | UserNameErrorDlg_Do() + | + +-------------------------------------------------------------------------+*/ +ULONG UserNameErrorDlg_Do(LPTSTR Title, LPTSTR Problem, USER_BUFFER *User) { + DLGPROC lpfnDlg; + + lstrcpy(OldName, User->Name); + lstrcpy(NewName, User->NewName); + MaxNameLen = MAX_USER_NAME_LEN; + + DlgTitle = Title; + NameErrorProblem = Problem; + lpfnDlg = MakeProcInstance((DLGPROC) NameErrorDlg, hInst); + CursorNormal(); + DialogBox(hInst, TEXT("NameError"), hStatus, lpfnDlg) ; + CursorHourGlass(); + FreeProcInstance(lpfnDlg); + + if (RetType == IDRETRY) { + User->err = 0; + lstrcpy(User->NewName, NewName); + + // if the name is different then flag that it is a new name + if (lstrcmpi(User->NewName, User->Name)) + User->IsNewName = TRUE; + } + + return RetType; + +} // UserNameErrorDlg_Do + + +/*+-------------------------------------------------------------------------+ + | GroupNameErrorDlg_Do() + | + +-------------------------------------------------------------------------+*/ +ULONG GroupNameErrorDlg_Do(LPTSTR Title, LPTSTR Problem, GROUP_BUFFER *Group) { + DLGPROC lpfnDlg; + + lstrcpy(OldName, Group->Name); + lstrcpy(NewName, Group->NewName); + MaxNameLen = MAX_NT_GROUP_NAME_LEN; + + DlgTitle = Title; + NameErrorProblem = Problem; + lpfnDlg = MakeProcInstance((DLGPROC) NameErrorDlg, hInst); + CursorNormal(); + DialogBox(hInst, TEXT("NameError"), hStatus, lpfnDlg) ; + CursorHourGlass(); + FreeProcInstance(lpfnDlg); + + if (RetType == IDRETRY) { + Group->err = 0; + lstrcpy(Group->NewName, NewName); + + // if the name is different then flag that it is a new name + if (lstrcmpi(Group->NewName, Group->Name)) + Group->IsNewName = TRUE; + } + + return RetType; + +} // GroupNameErrorDlg_Do + + diff --git a/private/nw/convert/nwconv/statbox.h b/private/nw/convert/nwconv/statbox.h new file mode 100644 index 000000000..070f67ce6 --- /dev/null +++ b/private/nw/convert/nwconv/statbox.h @@ -0,0 +1,46 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _HSTATBOX_ +#define _HSTATBOX_ + +#ifdef __cplusplus +extern "C"{ +#endif + +void Status_CurConv(UINT Num); +void Status_TotConv(UINT Num); +void Status_SrcServ(LPTSTR Server); +void Status_DestServ(LPTSTR Server); +void Status_ConvTxt(LPTSTR Text); +void Status_CurNum(UINT Num); +void Status_CurTot(UINT Num); +void Status_ItemLabel(LPTSTR Text, ...); +void Status_Item(LPTSTR Text); +void Status_TotComplete(UINT Num); +void Status_TotGroups(UINT Num); +void Status_TotUsers(UINT Num); +void Status_TotFiles(UINT Num); +void Status_TotErrors(UINT Num); +void Status_BytesTxt(LPTSTR Text); +void Status_Bytes(LPTSTR Text); +void Status_TotBytes(LPTSTR Text); +void Status_BytesSep(LPTSTR Text); + +void DoStatusDlg(HWND hDlg); +void StatusDlgKill(); + +void Panel_Line(int Line, LPTSTR szFormat, ...); +void PanelDlg_Do(HWND hDlg, LPTSTR Title); +BOOL Panel_Cancel(); +void PanelDlgKill(); + +ULONG UserNameErrorDlg_Do(LPTSTR Title, LPTSTR Problem, USER_BUFFER *User); +ULONG GroupNameErrorDlg_Do(LPTSTR Title, LPTSTR Problem, GROUP_BUFFER *Group); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/strings.h b/private/nw/convert/nwconv/strings.h new file mode 100644 index 000000000..212d31f08 --- /dev/null +++ b/private/nw/convert/nwconv/strings.h @@ -0,0 +1,478 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _STRINGS_ +#define _STRINGS_ + +#define MAX_STRING_SIZE 256 + +#define IDS_STRINGBASE (1500) + +#define IDS_APPNAME (IDS_STRINGBASE+1) + +#define IDS_DISK_SPACE_UNAVAIL (IDS_STRINGBASE+2) +#define IDS_DISK_SPACE (IDS_STRINGBASE+3) +#define IDS_MATH_COPR_NOTPRESENT (IDS_STRINGBASE+4) +#define IDS_MATH_COPR_PRESENT (IDS_STRINGBASE+5) +#define IDS_PHYSICAL_MEM (IDS_STRINGBASE+6) + +#define IDS_USERFILTERSTRING (IDS_STRINGBASE+7) +#define IDS_MAINFILTERSTRING (IDS_STRINGBASE+8) + +#define IDS_TXTWARNING (IDS_STRINGBASE+9) +#define IDS_RESTOREDEFAULTS (IDS_STRINGBASE+10) + +#define IDS_MAPNEWNAME (IDS_STRINGBASE+11) +#define IDS_MAPNEWPASSWORD (IDS_STRINGBASE+12) +#define IDS_MAPGROUPS (IDS_STRINGBASE+13) + +#define IDS_NOREADMAP (IDS_STRINGBASE+14) +#define IDS_MAPCREATED (IDS_STRINGBASE+15) +#define IDS_MAPCREATEFAIL (IDS_STRINGBASE+16) + +#define IDS_CRLF (IDS_STRINGBASE+17) + +#define IDS_SUN (IDS_STRINGBASE+18) +#define IDS_MON (IDS_STRINGBASE+19) +#define IDS_TUE (IDS_STRINGBASE+20) +#define IDS_WED (IDS_STRINGBASE+21) +#define IDS_THU (IDS_STRINGBASE+22) +#define IDS_FRI (IDS_STRINGBASE+23) +#define IDS_SAT (IDS_STRINGBASE+24) + +#define IDS_SUNDAY (IDS_STRINGBASE+25) +#define IDS_MONDAY (IDS_STRINGBASE+26) +#define IDS_TUESDAY (IDS_STRINGBASE+27) +#define IDS_WEDNESDAY (IDS_STRINGBASE+28) +#define IDS_THURSDAY (IDS_STRINGBASE+29) +#define IDS_FRIDAY (IDS_STRINGBASE+30) +#define IDS_SATURDAY (IDS_STRINGBASE+31) + +#define IDS_NWCANT_CON (IDS_STRINGBASE+32) +#define IDS_NWNO_ADMIN (IDS_STRINGBASE+33) + +#define IDS_LINE (IDS_STRINGBASE+34) +#define IDS_BRACE (IDS_STRINGBASE+35) +#define IDS_YES (IDS_STRINGBASE+36) +#define IDS_NO (IDS_STRINGBASE+37) + +#define IDS_E_NWLOG (IDS_STRINGBASE+38) +#define IDS_NOEDITMAP (IDS_STRINGBASE+39) + +#define IDS_LOCKED_OUT (IDS_STRINGBASE+40) + +///////////////// +#define IDS_D_STRINGBASE (IDS_STRINGBASE+40) + +#define IDS_D_1 (IDS_D_STRINGBASE+1) +#define IDS_D_2 (IDS_D_STRINGBASE+2) +#define IDS_D_3 (IDS_D_STRINGBASE+3) +#define IDS_D_4 (IDS_D_STRINGBASE+4) +#define IDS_D_5 (IDS_D_STRINGBASE+5) +#define IDS_D_6 (IDS_D_STRINGBASE+6) +#define IDS_D_7 (IDS_D_STRINGBASE+7) +#define IDS_D_8 (IDS_D_STRINGBASE+8) +#define IDS_D_9 (IDS_D_STRINGBASE+9) +#define IDS_D_10 (IDS_D_STRINGBASE+10) + +#define IDS_D_11 (IDS_D_STRINGBASE+11) +#define IDS_D_12 (IDS_D_STRINGBASE+12) + +#define IDS_D_13 (IDS_D_STRINGBASE+13) +#define IDS_D_14 (IDS_D_STRINGBASE+14) + +#define IDS_D_15 (IDS_D_STRINGBASE+15) +#define IDS_D_16 (IDS_D_STRINGBASE+16) + +#define IDS_D_17 (IDS_D_STRINGBASE+17) + +#define IDS_D_18 (IDS_D_STRINGBASE+18) +#define IDS_D_19 (IDS_D_STRINGBASE+19) + +#define IDS_D_20 (IDS_D_STRINGBASE+20) +#define IDS_D_21 (IDS_D_STRINGBASE+21) + +#define IDS_D_22 (IDS_D_STRINGBASE+22) + + +//////////// +#define IDS_S_STRINGBASE (IDS_D_STRINGBASE+22) + +#define IDS_S_1 (IDS_S_STRINGBASE+1) +#define IDS_S_2 (IDS_S_STRINGBASE+2) +#define IDS_S_3 (IDS_S_STRINGBASE+3) +#define IDS_S_4 (IDS_S_STRINGBASE+4) +#define IDS_S_5 (IDS_S_STRINGBASE+5) +#define IDS_S_6 (IDS_S_STRINGBASE+6) + +#define IDS_S_7 (IDS_S_STRINGBASE+7) +#define IDS_S_8 (IDS_S_STRINGBASE+8) + +#define IDS_S_9 (IDS_S_STRINGBASE+9) +#define IDS_S_10 (IDS_S_STRINGBASE+10) +#define IDS_S_11 (IDS_S_STRINGBASE+11) + +#define IDS_S_12 (IDS_S_STRINGBASE+12) +#define IDS_S_13 (IDS_S_STRINGBASE+13) +#define IDS_S_14 (IDS_S_STRINGBASE+14) + +#define IDS_S_15 (IDS_S_STRINGBASE+15) +#define IDS_S_16 (IDS_S_STRINGBASE+16) +#define IDS_S_17 (IDS_S_STRINGBASE+17) +#define IDS_S_18 (IDS_S_STRINGBASE+18) +#define IDS_S_19 (IDS_S_STRINGBASE+19) + +#define IDS_S_20 (IDS_S_STRINGBASE+20) + +#define IDS_S_21 (IDS_S_STRINGBASE+21) +#define IDS_S_22 (IDS_S_STRINGBASE+22) +#define IDS_S_23 (IDS_S_STRINGBASE+23) +#define IDS_S_24 (IDS_S_STRINGBASE+24) +#define IDS_S_25 (IDS_S_STRINGBASE+25) +#define IDS_S_26 (IDS_S_STRINGBASE+26) + +#define IDS_S_27 (IDS_S_STRINGBASE+27) + +#define IDS_S_28 (IDS_S_STRINGBASE+28) +#define IDS_S_29 (IDS_S_STRINGBASE+29) +#define IDS_S_30 (IDS_S_STRINGBASE+30) +#define IDS_S_31 (IDS_S_STRINGBASE+31) +#define IDS_S_32 (IDS_S_STRINGBASE+32) +#define IDS_S_33 (IDS_S_STRINGBASE+33) + +#define IDS_S_34 (IDS_S_STRINGBASE+34) + +#define IDS_S_35 (IDS_S_STRINGBASE+35) + +#define IDS_S_36 (IDS_S_STRINGBASE+36) +#define IDS_S_37 (IDS_S_STRINGBASE+37) + +#define IDS_S_38 (IDS_S_STRINGBASE+38) +#define IDS_S_39 (IDS_S_STRINGBASE+39) +#define IDS_S_40 (IDS_S_STRINGBASE+40) +#define IDS_S_41 (IDS_S_STRINGBASE+41) + +#define IDS_S_42 (IDS_S_STRINGBASE+42) +#define IDS_S_43 (IDS_S_STRINGBASE+43) + +#define IDS_S_44 (IDS_S_STRINGBASE+44) +#define IDS_S_45 (IDS_S_STRINGBASE+45) +#define IDS_S_46 (IDS_S_STRINGBASE+46) +#define IDS_S_47 (IDS_S_STRINGBASE+47) +#define IDS_S_48 (IDS_S_STRINGBASE+48) + +#define IDS_S_49 (IDS_S_STRINGBASE+49) + +//////////// +#define IDS_E_STRINGBASE (IDS_S_STRINGBASE+49) + +#define IDS_E_1 (IDS_E_STRINGBASE+1) +#define IDS_E_2 (IDS_E_STRINGBASE+2) +#define IDS_E_3 (IDS_E_STRINGBASE+3) +#define IDS_E_4 (IDS_E_STRINGBASE+4) +#define IDS_E_5 (IDS_E_STRINGBASE+5) +#define IDS_E_6 (IDS_E_STRINGBASE+6) +#define IDS_E_7 (IDS_E_STRINGBASE+7) +#define IDS_E_8 (IDS_E_STRINGBASE+8) +#define IDS_E_9 (IDS_E_STRINGBASE+9) + +#define IDS_E_10 (IDS_E_STRINGBASE+10) +#define IDS_E_11 (IDS_E_STRINGBASE+11) + +#define IDS_E_12 (IDS_E_STRINGBASE+12) + +#define IDS_E_13 (IDS_E_STRINGBASE+13) + +#define IDS_E_14 (IDS_E_STRINGBASE+14) + +#define IDS_E_15 (IDS_E_STRINGBASE+15) +#define IDS_E_16 (IDS_E_STRINGBASE+16) + +#define IDS_E_17 (IDS_E_STRINGBASE+17) + +#define IDS_E_18 (IDS_E_STRINGBASE+18) + +//////////// +#define IDS_M_STRINGBASE (IDS_E_STRINGBASE+18) + +#define IDS_M_1 (IDS_M_STRINGBASE+1) +#define IDS_M_2 (IDS_M_STRINGBASE+2) +#define IDS_M_3 (IDS_M_STRINGBASE+3) +#define IDS_M_4 (IDS_M_STRINGBASE+4) +#define IDS_M_5 (IDS_M_STRINGBASE+5) +#define IDS_M_6 (IDS_M_STRINGBASE+6) +#define IDS_M_7 (IDS_M_STRINGBASE+7) +#define IDS_M_8 (IDS_M_STRINGBASE+8) + +//////////// +#define IDS_L_STRINGBASE (IDS_M_STRINGBASE+8) + +#define IDS_L_1 (IDS_L_STRINGBASE+1) +#define IDS_L_2 (IDS_L_STRINGBASE+2) +#define IDS_L_3 (IDS_L_STRINGBASE+3) + +#define IDS_L_4 (IDS_L_STRINGBASE+4) +#define IDS_L_5 (IDS_L_STRINGBASE+5) +#define IDS_L_6 (IDS_L_STRINGBASE+6) + +#define IDS_L_7 (IDS_L_STRINGBASE+7) +#define IDS_L_8 (IDS_L_STRINGBASE+8) +#define IDS_L_9 (IDS_L_STRINGBASE+9) +#define IDS_L_10 (IDS_L_STRINGBASE+10) + +#define IDS_L_11 (IDS_L_STRINGBASE+11) +#define IDS_L_12 (IDS_L_STRINGBASE+12) +#define IDS_L_13 (IDS_L_STRINGBASE+13) +#define IDS_L_14 (IDS_L_STRINGBASE+14) +#define IDS_L_15 (IDS_L_STRINGBASE+15) +#define IDS_L_16 (IDS_L_STRINGBASE+16) + +#define IDS_L_17 (IDS_L_STRINGBASE+17) +#define IDS_L_18 (IDS_L_STRINGBASE+18) +#define IDS_L_19 (IDS_L_STRINGBASE+19) +#define IDS_L_20 (IDS_L_STRINGBASE+20) + +#define IDS_L_21 (IDS_L_STRINGBASE+21) +#define IDS_L_22 (IDS_L_STRINGBASE+22) + +#define IDS_L_23 (IDS_L_STRINGBASE+23) +#define IDS_L_24 (IDS_L_STRINGBASE+24) +#define IDS_L_25 (IDS_L_STRINGBASE+25) +#define IDS_L_26 (IDS_L_STRINGBASE+26) +#define IDS_L_27 (IDS_L_STRINGBASE+27) +#define IDS_L_28 (IDS_L_STRINGBASE+28) +#define IDS_L_29 (IDS_L_STRINGBASE+29) +#define IDS_L_30 (IDS_L_STRINGBASE+30) +#define IDS_L_31 (IDS_L_STRINGBASE+31) +#define IDS_L_32 (IDS_L_STRINGBASE+32) +#define IDS_L_33 (IDS_L_STRINGBASE+33) +#define IDS_L_34 (IDS_L_STRINGBASE+34) +#define IDS_L_35 (IDS_L_STRINGBASE+35) +#define IDS_L_36 (IDS_L_STRINGBASE+36) +#define IDS_L_37 (IDS_L_STRINGBASE+37) +#define IDS_L_38 (IDS_L_STRINGBASE+38) +#define IDS_L_39 (IDS_L_STRINGBASE+39) +#define IDS_L_40 (IDS_L_STRINGBASE+40) +#define IDS_L_41 (IDS_L_STRINGBASE+41) +#define IDS_L_42 (IDS_L_STRINGBASE+42) +#define IDS_L_43 (IDS_L_STRINGBASE+43) +#define IDS_L_44 (IDS_L_STRINGBASE+44) +#define IDS_L_45 (IDS_L_STRINGBASE+45) +#define IDS_L_46 (IDS_L_STRINGBASE+46) +#define IDS_L_47 (IDS_L_STRINGBASE+47) +#define IDS_L_48 (IDS_L_STRINGBASE+48) +#define IDS_L_49 (IDS_L_STRINGBASE+49) + +#define IDS_L_50 (IDS_L_STRINGBASE+50) +#define IDS_L_51 (IDS_L_STRINGBASE+51) + +#define IDS_L_52 (IDS_L_STRINGBASE+52) +#define IDS_L_53 (IDS_L_STRINGBASE+53) +#define IDS_L_54 (IDS_L_STRINGBASE+54) +#define IDS_L_55 (IDS_L_STRINGBASE+55) + +#define IDS_L_56 (IDS_L_STRINGBASE+56) +#define IDS_L_57 (IDS_L_STRINGBASE+57) +#define IDS_L_58 (IDS_L_STRINGBASE+58) +#define IDS_L_59 (IDS_L_STRINGBASE+59) +#define IDS_L_60 (IDS_L_STRINGBASE+60) +#define IDS_L_61 (IDS_L_STRINGBASE+61) +#define IDS_L_62 (IDS_L_STRINGBASE+62) +#define IDS_L_63 (IDS_L_STRINGBASE+63) +#define IDS_L_64 (IDS_L_STRINGBASE+64) +#define IDS_L_65 (IDS_L_STRINGBASE+65) +#define IDS_L_66 (IDS_L_STRINGBASE+66) +#define IDS_L_67 (IDS_L_STRINGBASE+67) +#define IDS_L_68 (IDS_L_STRINGBASE+68) +#define IDS_L_69 (IDS_L_STRINGBASE+69) +#define IDS_L_70 (IDS_L_STRINGBASE+70) +#define IDS_L_71 (IDS_L_STRINGBASE+71) +#define IDS_L_72 (IDS_L_STRINGBASE+72) +#define IDS_L_73 (IDS_L_STRINGBASE+73) +#define IDS_L_74 (IDS_L_STRINGBASE+74) +#define IDS_L_75 (IDS_L_STRINGBASE+75) + +#define IDS_L_76 (IDS_L_STRINGBASE+76) +#define IDS_L_77 (IDS_L_STRINGBASE+77) + +#define IDS_L_78 (IDS_L_STRINGBASE+78) +#define IDS_L_79 (IDS_L_STRINGBASE+79) +#define IDS_L_80 (IDS_L_STRINGBASE+80) +#define IDS_L_81 (IDS_L_STRINGBASE+81) +#define IDS_L_82 (IDS_L_STRINGBASE+82) +#define IDS_L_83 (IDS_L_STRINGBASE+83) +#define IDS_L_84 (IDS_L_STRINGBASE+84) +#define IDS_L_85 (IDS_L_STRINGBASE+85) +#define IDS_L_86 (IDS_L_STRINGBASE+86) +#define IDS_L_87 (IDS_L_STRINGBASE+87) +#define IDS_L_88 (IDS_L_STRINGBASE+88) +#define IDS_L_89 (IDS_L_STRINGBASE+89) +#define IDS_L_90 (IDS_L_STRINGBASE+90) +#define IDS_L_91 (IDS_L_STRINGBASE+91) +#define IDS_L_92 (IDS_L_STRINGBASE+92) +#define IDS_L_93 (IDS_L_STRINGBASE+93) + +#define IDS_L_94 (IDS_L_STRINGBASE+94) +#define IDS_L_95 (IDS_L_STRINGBASE+95) +#define IDS_L_96 (IDS_L_STRINGBASE+96) + +#define IDS_L_97 (IDS_L_STRINGBASE+97) +#define IDS_L_98 (IDS_L_STRINGBASE+98) +#define IDS_L_99 (IDS_L_STRINGBASE+99) +#define IDS_L_100 (IDS_L_STRINGBASE+100) + +#define IDS_L_101 (IDS_L_STRINGBASE+101) +#define IDS_L_102 (IDS_L_STRINGBASE+102) +#define IDS_L_103 (IDS_L_STRINGBASE+103) + +#define IDS_L_104 (IDS_L_STRINGBASE+104) + +#define IDS_L_105 (IDS_L_STRINGBASE+105) +#define IDS_L_106 (IDS_L_STRINGBASE+106) +#define IDS_L_107 (IDS_L_STRINGBASE+107) +#define IDS_L_108 (IDS_L_STRINGBASE+108) +#define IDS_L_109 (IDS_L_STRINGBASE+109) +#define IDS_L_110 (IDS_L_STRINGBASE+110) +#define IDS_L_111 (IDS_L_STRINGBASE+111) +#define IDS_L_112 (IDS_L_STRINGBASE+112) +#define IDS_L_113 (IDS_L_STRINGBASE+113) +#define IDS_L_114 (IDS_L_STRINGBASE+114) +#define IDS_L_115 (IDS_L_STRINGBASE+115) +#define IDS_L_116 (IDS_L_STRINGBASE+116) +#define IDS_L_117 (IDS_L_STRINGBASE+117) +#define IDS_L_118 (IDS_L_STRINGBASE+118) +#define IDS_L_119 (IDS_L_STRINGBASE+119) +#define IDS_L_120 (IDS_L_STRINGBASE+120) +#define IDS_L_121 (IDS_L_STRINGBASE+121) +#define IDS_L_122 (IDS_L_STRINGBASE+122) +#define IDS_L_123 (IDS_L_STRINGBASE+123) +#define IDS_L_124 (IDS_L_STRINGBASE+124) + +#define IDS_L_125 (IDS_L_STRINGBASE+125) + +#define IDS_L_126 (IDS_L_STRINGBASE+126) +#define IDS_L_127 (IDS_L_STRINGBASE+127) +#define IDS_L_128 (IDS_L_STRINGBASE+128) +#define IDS_L_129 (IDS_L_STRINGBASE+129) +#define IDS_L_130 (IDS_L_STRINGBASE+130) +#define IDS_L_131 (IDS_L_STRINGBASE+131) +#define IDS_L_132 (IDS_L_STRINGBASE+132) +#define IDS_L_133 (IDS_L_STRINGBASE+133) +#define IDS_L_134 (IDS_L_STRINGBASE+134) +#define IDS_L_135 (IDS_L_STRINGBASE+135) + +#define IDS_L_136 (IDS_L_STRINGBASE+136) +#define IDS_L_137 (IDS_L_STRINGBASE+137) +#define IDS_L_138 (IDS_L_STRINGBASE+138) +#define IDS_L_139 (IDS_L_STRINGBASE+139) +#define IDS_L_140 (IDS_L_STRINGBASE+140) +#define IDS_L_141 (IDS_L_STRINGBASE+141) +#define IDS_L_142 (IDS_L_STRINGBASE+142) +#define IDS_L_143 (IDS_L_STRINGBASE+143) +#define IDS_L_144 (IDS_L_STRINGBASE+144) +#define IDS_L_145 (IDS_L_STRINGBASE+145) +#define IDS_L_146 (IDS_L_STRINGBASE+146) +#define IDS_L_147 (IDS_L_STRINGBASE+147) +#define IDS_L_148 (IDS_L_STRINGBASE+148) +#define IDS_L_149 (IDS_L_STRINGBASE+149) +#define IDS_L_150 (IDS_L_STRINGBASE+150) +#define IDS_L_151 (IDS_L_STRINGBASE+151) +#define IDS_L_152 (IDS_L_STRINGBASE+152) +#define IDS_L_153 (IDS_L_STRINGBASE+153) +#define IDS_L_154 (IDS_L_STRINGBASE+154) + +#define IDS_L_155 (IDS_L_STRINGBASE+155) +#define IDS_L_156 (IDS_L_STRINGBASE+156) + +#define IDS_L_157 (IDS_L_STRINGBASE+157) +#define IDS_L_158 (IDS_L_STRINGBASE+158) +#define IDS_L_159 (IDS_L_STRINGBASE+159) + +#define IDS_L_160 (IDS_L_STRINGBASE+160) +#define IDS_L_161 (IDS_L_STRINGBASE+161) + +#define IDS_L_162 (IDS_L_STRINGBASE+162) +#define IDS_L_163 (IDS_L_STRINGBASE+163) +#define IDS_L_164 (IDS_L_STRINGBASE+164) + +#define IDS_L_165 (IDS_L_STRINGBASE+165) +#define IDS_L_166 (IDS_L_STRINGBASE+166) +#define IDS_L_167 (IDS_L_STRINGBASE+167) +#define IDS_L_168 (IDS_L_STRINGBASE+168) + +#define IDS_L_169 (IDS_L_STRINGBASE+169) +#define IDS_L_170 (IDS_L_STRINGBASE+170) +#define IDS_L_171 (IDS_L_STRINGBASE+171) + +#define IDS_L_172 (IDS_L_STRINGBASE+172) +#define IDS_L_173 (IDS_L_STRINGBASE+173) +#define IDS_L_174 (IDS_L_STRINGBASE+174) +#define IDS_L_175 (IDS_L_STRINGBASE+175) +#define IDS_L_176 (IDS_L_STRINGBASE+176) +#define IDS_L_177 (IDS_L_STRINGBASE+177) + +#define IDS_L_178 (IDS_L_STRINGBASE+178) +#define IDS_L_179 (IDS_L_STRINGBASE+179) + +#define IDS_L_180 (IDS_L_STRINGBASE+180) + +#define IDS_L_181 (IDS_L_STRINGBASE+181) + +#define IDS_L_182 (IDS_L_STRINGBASE+182) +#define IDS_L_183 (IDS_L_STRINGBASE+183) +#define IDS_L_184 (IDS_L_STRINGBASE+184) +#define IDS_L_185 (IDS_L_STRINGBASE+185) + +#define IDS_L_186 (IDS_L_STRINGBASE+186) +#define IDS_L_187 (IDS_L_STRINGBASE+187) +#define IDS_L_188 (IDS_L_STRINGBASE+188) + +#define IDS_L_189 (IDS_L_STRINGBASE+189) +#define IDS_L_190 (IDS_L_STRINGBASE+190) +#define IDS_L_191 (IDS_L_STRINGBASE+191) +#define IDS_L_192 (IDS_L_STRINGBASE+192) +#define IDS_L_193 (IDS_L_STRINGBASE+193) + +#define IDS_L_194 (IDS_L_STRINGBASE+194) +#define IDS_L_195 (IDS_L_STRINGBASE+195) +#define IDS_L_196 (IDS_L_STRINGBASE+196) +#define IDS_L_197 (IDS_L_STRINGBASE+197) + +#define IDS_L_198 (IDS_L_STRINGBASE+198) +#define IDS_L_199 (IDS_L_STRINGBASE+199) + +#define IDS_L_200 (IDS_L_STRINGBASE+200) +#define IDS_L_201 (IDS_L_STRINGBASE+201) + +#define IDS_L_202 (IDS_L_STRINGBASE+202) + +#define IDS_L_203 (IDS_L_STRINGBASE+203) +#define IDS_L_204 (IDS_L_STRINGBASE+204) +#define IDS_L_205 (IDS_L_STRINGBASE+205) +#define IDS_L_206 (IDS_L_STRINGBASE+206) + +#define IDS_L_207 (IDS_L_STRINGBASE+207) +#define IDS_L_208 (IDS_L_STRINGBASE+208) + +#define IDS_L_209 (IDS_L_STRINGBASE+209) +#define IDS_L_210 (IDS_L_STRINGBASE+210) +#define IDS_L_211 (IDS_L_STRINGBASE+211) + +#define IDS_L_212 (IDS_L_STRINGBASE+212) + +#define IDS_L_213 (IDS_L_STRINGBASE+213) +#define IDS_L_214 (IDS_L_STRINGBASE+214) + +#define IDS_L_215 (IDS_L_STRINGBASE+215) +#define IDS_L_216 (IDS_L_STRINGBASE+216) + +#define IDS_L_217 (IDS_L_STRINGBASE+217) + +#define IDS_L_218 (IDS_L_STRINGBASE+218) +#define IDS_L_219 (IDS_L_STRINGBASE+219) + +#define STRING_TABLE_END (IDS_L_STRINGBASE+219) + +#define TOTAL_STRINGS (STRING_TABLE_END - IDS_STRINGBASE) +#endif diff --git a/private/nw/convert/nwconv/switches.h b/private/nw/convert/nwconv/switches.h new file mode 100644 index 000000000..a42c1f031 --- /dev/null +++ b/private/nw/convert/nwconv/switches.h @@ -0,0 +1,12 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _SWITCHES_ +#define _SWITCHES_ + +#if DBG && !defined(DEBUG) +#define DEBUG +#endif + +#endif diff --git a/private/nw/convert/nwconv/tab.c b/private/nw/convert/nwconv/tab.c new file mode 100644 index 000000000..f5a917331 --- /dev/null +++ b/private/nw/convert/nwconv/tab.c @@ -0,0 +1,1512 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright 1990-1993 Microsoft corporation +// all rights reservered +////////////////////////////////////////////////////////////////////////////// +// +// Program: (nominally)Bloodhound +// Module: tab.c +// Purpose: creates and operates a book tab (big file folder) custom control +// +// Note: the current implementation is limited to 4 booktabs, sorry. +// +// +// ---------------------------- TABSTOP = 4 ------------------- +// +// Entry Points: +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// BookTab +// +// +// +// Input: +// hwnd - our window handle +// +// Returns: +// +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +#define STRICT +#include "switches.h" +#include +#include + +#include "tab.h" +// #include "..\bhmem.h" + +////////////////////////////////////////////////////////////////////////////// +// Constants +////////////////////////////////////////////////////////////////////////////// +#define MAX_TABS 4 +#define MAX_TAB_LABEL_LEN 128 + +#define ANGLE_X 5 +#define ANGLE_Y 5 + +#define CARAT_X 2 +#define CARAT_Y 2 + +#define FLUFF_X 0 +#define FLUFF_Y 0 + +#define FOOTROOM_Y 3 + +// We use the selected tab for these calculations: +// +// tab_rect: +// +// ANGLE_X|--| +// +// - BBBBBBBBBBBBBBB +// ANGLE_Y | BWWWWWWWWWWWWWWW +// | BWWWWWWWWWWWWWWWW +// - BWWW +// BWW * <-- this is where the text_rect starts +// BWW +// BWW +// +// +// text_rect: (defined by the *'s) +// +// FLUFF_X|----| +// +// - * * +// | +// FLUFF_Y | +// | CARAT_X +// | |---| +// - ............................. - +// . . | +// . . | CARAT_Y +// . . | +// - . XXXXX XXXXX X X XXXXX . - +// text hght| . X X X X X . +// is from | . X XXX X X . +// font | . X X X X X . +// _ . X XXXXX X X X . +// . . +// . . +// . . +// ............................. +// +// |---------------------| +// text width is directly +// from the font itself +// * * +// +// + + +////////////////////////////////////////////////////////////////////////////// +// Data Structures for this file +////////////////////////////////////////////////////////////////////////////// +typedef struct _ONETAB +{ + TCHAR label[ MAX_TAB_LABEL_LEN + 1 ]; + DWORD data; + RECT tab_rect; + RECT text_rect; +} ONETAB; + +typedef struct _TABDATA +{ + // do the tabs need updating ? + BOOL fUpdate; + RECT tabs_rect; + + // font data + HFONT hfSelected; + HFONT hfUnselected; + + // windows data + HWND hwndParent; + + // tab data + UINT total_tabs; + UINT selected_tab; + ONETAB tab[ MAX_TABS ]; + +} TABDATA; +typedef TABDATA *LPTABDATA; + + +////////////////////////////////////////////////////////////////////////////// +// Variables Global to this file +////////////////////////////////////////////////////////////////////////////// +TCHAR szBookTabName[]=BOOK_TAB_CONTROL; + +////////////////////////////////////////////////////////////////////////////// +// Macros Global to this file +////////////////////////////////////////////////////////////////////////////// +#define GetInstanceDataPtr(hwnd) ((LPTABDATA)GetWindowLong(hwnd, 0)) +#define SetInstanceDataPtr(hwnd,x) (SetWindowLong(hwnd, 0, (DWORD)x)) + + +////////////////////////////////////////////////////////////////////////////// +// Functional Prototypes for Functions Local to this File +////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK BookTab_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +BOOL BookTab_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct); +void BookTab_OnDestroy(HWND hwnd); +void BookTab_OnLButtonDown(HWND hwnd, BOOL fDblClk, int x, int y, UINT keyFlags); +void BookTab_OnPaint(HWND hwnd); +UINT BookTab_OnGetDlgCode(HWND hwnd, MSG FAR* lpmsg); +void BookTab_OnSize(HWND hwnd, UINT state, int cx, int cy); +void BookTab_OnSetFocus(HWND hwnd, HWND hwndOldFocus); +void BookTab_OnKillFocus(HWND hwnd, HWND hwndNewFocus); +void BookTab_OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags); +void BookTab_OnEnable(HWND hwnd, BOOL fEnable); + +UINT BookTab_OnAddItem( HWND hwnd, LPTSTR text ); +UINT BookTab_OnInsertItem( HWND hwnd, UINT index, LPTSTR text); +BOOL BookTab_OnDeleteItem( HWND hwnd, UINT index ); +BOOL BookTab_OnDeleteAllItems( HWND hwnd); +BOOL BookTab_OnSetItem( HWND hwnd, UINT index, LPTSTR text ); +BOOL BookTab_OnGetItem( HWND hwnd, UINT index, LPTSTR text ); +UINT BookTab_OnSetCurSel( HWND hand, UINT newsel ); +UINT BookTab_OnGetCurSel( HWND hand ); +UINT BookTab_OnGetItemCount( HWND hwnd ); +BOOL BookTab_OnSetItemData( HWND hwnd, UINT index, DWORD data ); +DWORD BookTab_OnGetItemData( HWND hwnd, UINT index); +void BookTab_OnPutInBack( HWND hwnd ); + +BOOL IsPointInRect( int given_x, int given_y, LPRECT pRect ); +void BookTab_UpdateButtons( HWND hwnd ); + +////////////////////////////////////////////////////////////////////////////// +// BookTab_Initialize() +// +// Initializes and registers the BookTab custom class +// +// Input: +// hInstance - the handle to our parent's instance +// +// Returns: +// True if successful, else False +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_Initialize(HINSTANCE hInstance) +{ + WNDCLASS wndclass; + + wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS | CS_PARENTDC; + wndclass.lpfnWndProc = BookTab_WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof( LPTABDATA ); + wndclass.hInstance = hInstance; + wndclass.hIcon = NULL; + wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szBookTabName; + + RegisterClass ( &wndclass ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_WndProc() +// +// Distributes messages coming in to the BookTab control +// +// Input: +// hwnd - Our handle +// message - the ordinal of the incoming message +// wParam - half of the incoming data +// lParam - the other half of the incoming data +// +// Returns: +// True if we handled the message, else False +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK BookTab_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + // standard windows messages + HANDLE_MSG( hwnd, WM_CREATE, BookTab_OnCreate); + HANDLE_MSG( hwnd, WM_DESTROY, BookTab_OnDestroy); + HANDLE_MSG( hwnd, WM_LBUTTONDOWN, BookTab_OnLButtonDown); + HANDLE_MSG( hwnd, WM_PAINT, BookTab_OnPaint); + HANDLE_MSG( hwnd, WM_SIZE, BookTab_OnSize); + HANDLE_MSG( hwnd, WM_SETFOCUS, BookTab_OnSetFocus); + HANDLE_MSG( hwnd, WM_KILLFOCUS, BookTab_OnKillFocus); + HANDLE_MSG( hwnd, WM_KEYDOWN, BookTab_OnKey); + HANDLE_MSG( hwnd, WM_KEYUP, BookTab_OnKey); + + // messages specific to all custom controls + HANDLE_MSG( hwnd, WM_GETDLGCODE, BookTab_OnGetDlgCode); + HANDLE_MSG( hwnd, WM_ENABLE, BookTab_OnEnable); + + // messages specific to THIS custom control + case BT_ADDITEM: + return( BookTab_OnAddItem( hwnd, (LPTSTR)lParam )); + case BT_INSERTITEM: + return( BookTab_OnInsertItem( hwnd, (UINT)wParam, (LPTSTR)lParam )); + case BT_DELETEITEM: + return( BookTab_OnDeleteItem( hwnd, (UINT)wParam )); + case BT_DELETEALLITEMS: + return( BookTab_OnDeleteAllItems( hwnd )); + case BT_SETITEM: + return( BookTab_OnSetItem( hwnd, (UINT)wParam, (LPTSTR)lParam )); + case BT_GETITEM: + return( BookTab_OnGetItem( hwnd, (UINT)wParam, (LPTSTR)lParam )); + case BT_SETCURSEL: + return( BookTab_OnSetCurSel( hwnd, (UINT)wParam )); + case BT_GETCURSEL: + return( BookTab_OnGetCurSel( hwnd )); + case BT_GETITEMCOUNT: + return( BookTab_OnGetItemCount( hwnd )); + case BT_SETITEMDATA: + return( BookTab_OnSetItemData( hwnd, (UINT)wParam, (DWORD)lParam )); + case BT_GETITEMDATA: + return( BookTab_OnGetItemData( hwnd, (UINT)wParam )); + case BT_PUTINBACK: + BookTab_OnPutInBack( hwnd ); + return (TRUE); + } + // pass unprocessed messages to DefWndProc... + return DefWindowProc(hwnd, message, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnCreate() +// +// Initializes a new instance of our lovely custom control +// +// Input: +// hwnd - our window handle +// lpcreatestruct - pointer to the data with which to do our thing +// +// Returns: +// True if the instance is created, else false +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct) +{ + LPTABDATA pData; + UINT i; + + // allocate the instance data for this control + pData = LocalAlloc( LPTR, sizeof( TABDATA )); + if( pData == NULL ) + return FALSE; + SetInstanceDataPtr( hwnd, pData ); + + // initialize values in the control + pData->total_tabs = 0; + pData->selected_tab = 0; + + pData->hwndParent = lpCreateStruct->hwndParent; + + // fill the prospective tab slots with data + for( i = 0; i < MAX_TABS; i++ ) + { + pData->tab[i].label[0] = TEXT('\0'); + pData->tab[i].data = (DWORD)0; + } + +#ifdef JAPAN // BookTab_OnCreate() + // create the proper fonts: + // 8 pt MS Gothic bold for selected and + // 8 pt MS Gothic regular for not selected + { + #ifdef UNICODE + WCHAR szGothic[] = {0xff2d, 0xff33, 0x20, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; + #else + #error Ansi string of szGothic is nessesory. + #endif + + pData->hfSelected = CreateFont( -8, 0, 0, 0, + FW_BOLD, FALSE, FALSE, FALSE, + SHIFTJIS_CHARSET, OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + 0x4, szGothic ); + pData->hfUnselected = CreateFont( -8, 0, 0, 0, + FW_NORMAL, FALSE, FALSE, FALSE, + SHIFTJIS_CHARSET, OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + 0x4, szGothic ); + } +#else + // create the proper fonts: + // 8 pt sans serif bold for selected and + // 8 pt sans serif regular for not selected + pData->hfSelected = CreateFont( -8, 0, 0, 0, + FW_BOLD, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + 0x4, TEXT("MS Sans Serif") ); + pData->hfUnselected = CreateFont( -8, 0, 0, 0, + FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + 0x4, TEXT("MS Sans Serif") ); +#endif // JAPAN + + // fill the rest of the sizing info + BookTab_OnSize( hwnd, 0, lpCreateStruct->cx, lpCreateStruct->cy ); + + // make sure that we are on the bottom + SetWindowPos( hwnd, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW ); + + // make sure we update + pData->fUpdate = TRUE; + + // put us last + BookTab_PutInBack( hwnd ); + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnDestroy() +// +// Cleans up as our control goes away +// +// Input: +// hwnd - our window handle +// +// Returns: +// nothing +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnDestroy(HWND hwnd) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // delete our fonts + DeleteObject( pData->hfSelected ); + DeleteObject( pData->hfUnselected ); + + // free up our instance data + LocalFree( pData ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnLButtonDown() +// +// Handles the event where a user has the left mouse button down +// +// Input: +// hwnd - our window handle +// fDblClk - an indication on the second message of a double click +// x - the mouses x coordinate at the time of the message +// y - the mouses y coordinate at the time of the message +// keyFlags - an indication of which keys were pressed at the time +// +// Returns: +// nuthin' +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnLButtonDown(HWND hwnd, BOOL fDblClk, int x, int y, UINT keyFlags) +{ + LPTABDATA pData; + UINT i; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // where did they click the mouse... + // loop thru the tabs to find the one struck + for( i = 0; i < pData->total_tabs; i++ ) + { + if( IsPointInRect( x, y, &(pData->tab[i].tab_rect) ) ) + { + // this is the correct spot + BookTab_OnSetCurSel( hwnd, i ); + + // notify our parent that the selection has changed + SendMessage( pData->hwndParent, BTN_SELCHANGE, + pData->selected_tab, (DWORD)hwnd); + + SetFocus( hwnd ); + return; + } + } + + // the mouse was clicked outside any of the button areas +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnPaint() +// +// Handles requests from windows that the control repaint itself +// +// Input: +// hwnd - our window handle +// +// Returns: +// hopefully :) +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnPaint(HWND hwnd) +{ + LPTABDATA pData; + PAINTSTRUCT ps; + HDC hdc; + TEXTMETRIC tm; + UINT i; + HWND hwndFocus; + + HPEN hOldPen; + HPEN hShadowPen; + HPEN hHighlightPen; + HPEN hFramePen; + HPEN hBackPen; + HBRUSH hBackBrush; + HFONT hfOldFont; + + WORD cyChar; + WORD yWidth; + WORD xWidth; + RECT total; + RECT temp; + LPRECT pTab; + LPRECT pText; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // right before drawing, make sure that the button sizes are accurate + BookTab_UpdateButtons( hwnd ); + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // get the handle to the window with the current focus + hwndFocus = GetFocus(); + + // prepare for painting... + BeginPaint( hwnd, &ps ); + hdc = GetDC( hwnd ); + + // set text stuff + SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); + SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); + SetTextAlign( hdc, TA_TOP | TA_LEFT ); + + // determine proper sizes + GetTextMetrics(hdc, &tm); + cyChar = (WORD)tm.tmHeight; + xWidth = GetSystemMetrics(SM_CXBORDER); + yWidth = GetSystemMetrics(SM_CYBORDER); + GetClientRect( hwnd, &total ); + //BUGBUG fudge the rectangle so that the bottom and left do not get cut off + total.bottom -= yWidth; + total.right -= xWidth; + + // set up the pens that we will need + hHighlightPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNHIGHLIGHT)); + hShadowPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNSHADOW)); + hFramePen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_WINDOWFRAME)); + hBackPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNFACE)); + hBackBrush = CreateSolidBrush( GetSysColor(COLOR_BTNFACE)); + + // get the old pen by setting a new one + hOldPen = SelectPen( hdc, hHighlightPen ); + + // clear out behind the tabs if we need to + if( pData->fUpdate == TRUE ) + { + FillRect( hdc, &(pData->tabs_rect), hBackBrush ); + pData->fUpdate = FALSE; + } + + // draw the box... + // left side dark border + SelectPen( hdc, hFramePen ); + MoveToEx( hdc, total.left, pData->tab[0].tab_rect.bottom+yWidth, NULL ); + LineTo ( hdc, total.left, total.bottom ); + // bottom dark border + LineTo ( hdc, total.right, total.bottom ); + // right side dark border + LineTo ( hdc, total.right, pData->tab[0].tab_rect.bottom+yWidth); + // top dark border, right half (over to selection) + LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-yWidth, + pData->tab[0].tab_rect.bottom+yWidth); + // skip area under the selected tab + MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left, + pData->tab[0].tab_rect.bottom+yWidth, NULL); + // top dark border, left half (from selection to left border) + LineTo ( hdc, total.left, pData->tab[0].tab_rect.bottom+yWidth); + + // left side highlight #1 + SelectPen( hdc, hHighlightPen ); + MoveToEx( hdc, total.left+xWidth, pData->tab[0].tab_rect.bottom+2*yWidth, NULL ); + LineTo( hdc, total.left+xWidth, total.bottom-yWidth ); + + // bottom shadow #1 + SelectPen( hdc, hShadowPen ); + LineTo( hdc, total.right-xWidth, total.bottom-yWidth ); + // right side shadow #1 + LineTo( hdc, total.right-xWidth, pData->tab[0].tab_rect.bottom+2*yWidth ); + + // top hilite #1 + SelectPen( hdc, hHighlightPen ); + // top hilite, right half (over to selection) + LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-yWidth, + pData->tab[0].tab_rect.bottom+2*yWidth); + // skip area under the selected tab + MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left, + pData->tab[0].tab_rect.bottom+2*yWidth, NULL); + // top hilite, left half (from selection to left border) + if( pData->selected_tab != 0 ) + LineTo ( hdc, total.left+2*xWidth, + pData->tab[0].tab_rect.bottom+2*yWidth); + + // left side highlight #2 + SelectPen( hdc, hHighlightPen ); + MoveToEx( hdc, total.left+2*xWidth, pData->tab[0].tab_rect.bottom+3*yWidth, NULL ); + LineTo( hdc, total.left+2*xWidth, total.bottom-2*yWidth ); + + // bottom shadow #2 + SelectPen( hdc, hShadowPen ); + LineTo( hdc, total.right-2*xWidth, total.bottom-2*yWidth ); + // right side shadow #2 + LineTo( hdc, total.right-2*xWidth, pData->tab[0].tab_rect.bottom+3*yWidth ); + + // top hilite #2 + SelectPen( hdc, hHighlightPen ); + // top hilite, right half (over to selection) + LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-2*yWidth, + pData->tab[0].tab_rect.bottom+3*yWidth); + // skip area under the selected tab + MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left, + pData->tab[0].tab_rect.bottom+3*yWidth, NULL); + // top hilite, left half (from selection to left border) + if( pData->selected_tab != 0 ) + LineTo ( hdc, total.left+2*xWidth, + pData->tab[0].tab_rect.bottom+3*yWidth); + + // Draw the tabs... + // loop thru the tabs + for( i = 0; i < pData->total_tabs; i++ ) + { + // point our local variables at the current rects + pTab = &(pData->tab[i].tab_rect); + pText = &(pData->tab[i].text_rect); + + if( i == pData->selected_tab ) + { + // this is the selection, it should not be pushed down... + // left side dark border + SelectPen( hdc, hFramePen ); + MoveToEx(hdc, pTab->left, pTab->bottom, NULL); + LineTo(hdc, pTab->left, pTab->top + ANGLE_Y*yWidth); + // left side angle dark border + LineTo(hdc, pTab->left + ANGLE_X*xWidth, pTab->top); + // top dark border + LineTo(hdc, pTab->right - ANGLE_X*xWidth, pTab->top); + // right side angle dark border + LineTo(hdc, pTab->right, pTab->top + ANGLE_Y*yWidth); + // right side dark border (overshoot by one) + LineTo(hdc, pTab->right, pTab->bottom+yWidth); + + // left side hilite #1 (extends down 3 below the box to handle + // melding the hilites with the box below) + SelectPen( hdc, hHighlightPen); + MoveToEx(hdc, pTab->left+xWidth, pTab->bottom+3*yWidth, NULL); + LineTo(hdc, pTab->left+xWidth, pTab->top+ANGLE_Y*yWidth ); + // left side angle hilight #1 + LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+yWidth ); + // top hilite #1 + LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+yWidth ); + // right side angle shadow #1 + SelectPen( hdc, hShadowPen); + LineTo(hdc, pTab->right-xWidth, pTab->top+ANGLE_Y*yWidth ); + // right side shadow #1 (overshoot by one) (see above) + LineTo(hdc, pTab->right-xWidth, pTab->bottom+3*yWidth); + + // left side hilite #2 (the 2* are becaus we are the 2nd hilite) + SelectPen( hdc, hHighlightPen); + MoveToEx(hdc, pTab->left+2*xWidth, pTab->bottom+3*yWidth, NULL); + LineTo(hdc, pTab->left+2*xWidth, pTab->top+ANGLE_Y*yWidth ); + // left side angle hilight #2 + LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+2*yWidth ); + // top hilite #2 + LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+2*yWidth ); + // right side angle shadow #2 + SelectPen( hdc, hShadowPen); + LineTo(hdc, pTab->right-2*xWidth, pTab->top+ANGLE_Y*yWidth ); + // right side shadow #2 (overshoot by one) + LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+4*yWidth ); + + // clear out the chunk below the active tab + SelectPen(hdc, hBackPen ); + MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+yWidth, NULL); + LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+yWidth); + MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+2*yWidth, NULL); + LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+2*yWidth); + MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+3*yWidth, NULL); + LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+3*yWidth); + + // clear out the old label... + FillRect( hdc, pText, hBackBrush ); + + // now print in the label ... + hfOldFont = SelectObject( hdc, pData->hfSelected ); + ExtTextOut( hdc, + pText->left+ CARAT_X*xWidth + FLUFF_X*xWidth, + pText->top + CARAT_Y*yWidth + FLUFF_Y*yWidth, + 0, NULL, pData->tab[i].label, + lstrlen(pData->tab[i].label), NULL ); + SelectFont( hdc, hfOldFont ); + + // if we have the focus, print the caret + if( hwnd == hwndFocus ) + { + // we have the focus + temp.top = pText->top + FLUFF_X*xWidth; + temp.left = pText->left + FLUFF_Y*yWidth; + temp.bottom = pText->bottom - FLUFF_X*xWidth; + temp.right = pText->right - FLUFF_Y*yWidth; + DrawFocusRect( hdc, &temp ); + } + + } + else + { + // push this tab down one border width... + // this will mean an extra +1 on all ANGLE_Ys... + // left side dark border + SelectPen( hdc, hFramePen ); + MoveToEx(hdc, pTab->left, pTab->bottom, NULL); + LineTo(hdc, pTab->left, pTab->top + (ANGLE_Y+1)*yWidth); + // left side angle dark border + LineTo(hdc, pTab->left + ANGLE_X*xWidth, pTab->top+yWidth); + // top dark border + LineTo(hdc, pTab->right - ANGLE_X*yWidth, pTab->top+yWidth); + // right side angle dark border + LineTo(hdc, pTab->right, pTab->top + (ANGLE_Y+1)*yWidth); + // right side dark border (overshoot by one) + LineTo(hdc, pTab->right, pTab->bottom+yWidth); + + // left side hilite + SelectPen( hdc, hHighlightPen); + MoveToEx(hdc, pTab->left+xWidth, pTab->bottom, NULL); + LineTo(hdc, pTab->left+xWidth, pTab->top+(ANGLE_Y+1)*yWidth); + // left side angle hilight + LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+2*yWidth); + // top hilite + LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+2*yWidth); + + // right side angle shadow + SelectPen( hdc, hShadowPen); + LineTo(hdc, pTab->right-xWidth, pTab->top+(ANGLE_Y+1)*yWidth); + // right side shadow (overshoot by one) + LineTo(hdc, pTab->right-xWidth, pTab->bottom+yWidth); + + // clean above left angle + SelectPen( hdc, hBackPen ); + MoveToEx(hdc, pTab->left, pTab->top+ANGLE_Y*yWidth, NULL ); + LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top ); + // clean above top + LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top); + // clean above right angle + LineTo(hdc, pTab->right, pTab->top+ANGLE_Y*yWidth ); + // clean last corner + LineTo(hdc, pTab->right, pTab->top+(ANGLE_Y+1)*yWidth ); + + // clean up inside left hilite + MoveToEx(hdc, pTab->left+2*xWidth, pTab->bottom, NULL ); + LineTo(hdc, pTab->left+2*xWidth, pTab->top+(ANGLE_Y+1)*yWidth); + // clean up inside left angle hilite + LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+3*yWidth); + // clean up inside top hilite (noop) + LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+3*yWidth); + // clean up inside right angle shadow (noop) + LineTo(hdc, pTab->right-2*xWidth, pTab->top+(ANGLE_Y+1)*yWidth); + // clean up inside left hilite (overshoot by one) + LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+yWidth); + + // clear out the old label... + FillRect( hdc, pText, hBackBrush ); + + // now print in the label ... + hfOldFont = SelectObject( hdc, pData->hfUnselected ); + ExtTextOut( hdc, + pText->left+ CARAT_X*xWidth + FLUFF_X*xWidth, + pText->top + CARAT_Y*yWidth + FLUFF_Y*yWidth + yWidth, + 0, NULL, pData->tab[i].label, + lstrlen(pData->tab[i].label), NULL ); + SelectFont( hdc, hfOldFont ); + } + } + + SelectPen( hdc, hOldPen); + + // put the DC we used back into circulation + ReleaseDC( hwnd, hdc ); + + // tell windows that we're done + EndPaint( hwnd, &ps ); + + // clean up + DeleteObject( hHighlightPen ); + DeleteObject( hShadowPen ); + DeleteObject( hFramePen ); + DeleteObject( hBackPen ); + DeleteObject( hBackBrush ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnSize() +// +// Handles requests from windows that we should resize ourselves +// +// Input: +// hwnd - our window handle +// state - an indication of Minimized, maximized, iconic, blah blah blah +// cx - our new width +// cy - our new height +// +// Returns: +// hopefully :) +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnSize(HWND hwnd, UINT state, int cx, int cy) +{ + // need to update the button size stuff, just for hit testing + BookTab_UpdateButtons(hwnd); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnSetFocus() +// +// Handles windows telling us that we just got the focus +// +// Input: +// hwnd - our window handle +// hwndOld - the guy who used to have the focus (i don't use) +// +// Returns: +// nyaytay +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnSetFocus(HWND hwnd, HWND hwndOldFocus) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that we are on the bottom + SetWindowPos( hwnd, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW ); + + // we gotta repaint just the rect for the active tab + InvalidateRect( hwnd, &(pData->tab[pData->selected_tab].tab_rect), FALSE ); + UpdateWindow( hwnd ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnKillFocus() +// +// Handles windows telling us that we are just about to lose the focus +// +// Input: +// hwnd - our window handle +// hwndNew - the lucky guy who is about to have the focus (i don't use) +// +// Returns: +// nyaytay +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnKillFocus(HWND hwnd, HWND hwndNewFocus) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // we gotta repaint just the rect for the active tab + InvalidateRect( hwnd, &(pData->tab[pData->selected_tab].tab_rect), FALSE ); + UpdateWindow( hwnd ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnKey() +// +// Handes key messages sent to the control +// +// Input: +// hwnd - our window handle +// vk - the virtual key code +// fDown - is the key down? +// cRepeat - how many times it was pressed +// flags - i don't use +// +// Returns: +// nada +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // don't want key up messages + if( fDown == FALSE ) + return; + + // we only handle left and right cursor + switch( vk ) + { + case VK_LEFT: + // move to the tab to the left (wrap if needed) + BookTab_OnSetCurSel( hwnd, (pData->selected_tab == 0)? + (pData->total_tabs-1):(pData->selected_tab-1)); + + // notify our parent that the selection has changed + SendMessage( pData->hwndParent, BTN_SELCHANGE, + pData->selected_tab, (DWORD)hwnd); + break; + + + + case VK_RIGHT: + BookTab_OnSetCurSel( hwnd, + (pData->selected_tab+1) % (pData->total_tabs)); + + // notify our parent that the selection has changed + SendMessage( pData->hwndParent, BTN_SELCHANGE, + pData->selected_tab, (DWORD)hwnd); + break; + } +} + + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnGetDlgCode() +// +// The windows dialog manager is asking us what type of user inputs we want +// +// Input: +// hwnd - our window handle +// lpmsg - who knows, I don't use it, it's not in the paper docs... +// +// Returns: +// a word which is a bitmap of input types +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnGetDlgCode(HWND hwnd, MSG FAR* lpmsg) +{ + // We just want cursor keys and character keys + return( DLGC_WANTARROWS | DLGC_WANTCHARS ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnEnable() +// +// Windows is telling us that we are being enabled/disabled +// +// Input: +// hwnd - our window handle +// fEnable - Are we being enabled? +// +// Returns: +// nada +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnEnable(HWND hwnd, BOOL fEnable) +{ + // BUGBUG - we look no different in either state +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnAddItem() +// +// Adds an item to the end of the tab list +// +// Input: +// hwnd - our window handle +// text - the label of the tab to add +// +// Returns: +// the index of the item as added +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnAddItem( HWND hwnd, LPTSTR text ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // call the worker for insert with the current end of the tab lizst + return( BookTab_OnInsertItem( hwnd, pData->total_tabs, text) ); +} + + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnInsertItem() +// +// Inserts the given item at the spot indicated and shoves the others down +// +// Input: +// hwnd - our window handle +// index - the proposed index of the new item +// text - the label to add to the new tab +// +// Returns: +// the ACTUAL new index of the item (we could sort or have to reduce +// the initial request if it would leave a gap) +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnInsertItem( HWND hwnd, UINT index, LPTSTR text) +{ + LPTABDATA pData; + int i; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that the text will fit + if( lstrlen( text ) > MAX_TAB_LABEL_LEN-1 ) + return (UINT)-1; + + // are we full + // BUGBUG, silly limit in the future + if( pData->total_tabs >= MAX_TABS ) + // we can not add at this time + return (UINT)-1; + + // make sure that the requested index is within or adjacent to currently + // used spots + if( index > pData->total_tabs ) + // change it so that index now points at the next open slot + index = pData->total_tabs; + + // slide over all tabs above + for( i = (int)pData->total_tabs; i > (int)index; i-- ) + { + memcpy( &(pData->tab[i]), &(pData->tab[i-1]), sizeof( ONETAB) ); + } + + // your room is ready sir + lstrcpy( pData->tab[index].label, text ); + pData->total_tabs++; + + // should clear the background + pData->fUpdate = TRUE; + + return index; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnDeleteItem() +// +// Deletes the item at the index given and closes up the gaps +// +// Input: +// hwnd - our window handle +// index - item to be deleted +// +// Returns: +// nuthin' +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnDeleteItem( HWND hwnd, UINT index ) +{ + LPTABDATA pData; + UINT i; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that we even have an element like this + if( index >= pData->total_tabs ) + return FALSE; + + // slide all of the deceased successors over + for( i = index+1; i < pData->total_tabs; i++ ) + { + memcpy( &(pData->tab[i-1]), &(pData->tab[i]), sizeof( ONETAB) ); + } + + // reduce the count to account for the deletion + pData->total_tabs--; + + // should clear the background + pData->fUpdate = TRUE; + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnDeleteAllItems() +// +// Genocide on tabs +// +// Input: +// hwnd - our window handle +// +// Returns: +// nothing +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnDeleteAllItems( HWND hwnd) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // BUGBUG just set our count to zero + pData->total_tabs = 0; + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnSetItem() +// +// Sets the title of the booktab given +// +// Input: +// hwnd - our window handle +// index - the tab to label +// text - the words to put on the tab +// +// Returns: +// TRUE if successful, else False +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnSetItem( HWND hwnd, UINT index, LPTSTR text ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that the text will fit + if( lstrlen( text ) > MAX_TAB_LABEL_LEN-1 ) + return FALSE; + + // make sure that the index is legal + if( index >= pData->total_tabs ) + return FALSE; + + // set the title + lstrcpy( pData->tab[index].label, text ); + + // we are changing the size of the tab, we will need to clean out behind + pData->fUpdate = TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnGetItem() +// +// Retrieves a booktab title +// +// Input: +// hwnd - our window handle +// index - the tab to label +// text - the buffer to fill with the tab title +// +// Returns: +// a pointer to the filled buffer if successful, else NULL +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnGetItem( HWND hwnd, UINT index, LPTSTR text ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that the index is legal + if( index >= pData->total_tabs ) + return FALSE; + + // get the title + lstrcpy( text, pData->tab[index].label ); + return( TRUE ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnSetCurSel() +// +// Sets the current selection +// +// Input: +// hwnd - our window handle +// newsel - the requested selection +// +// Returns: +// the new current selection +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnSetCurSel( HWND hwnd, UINT newsel ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // make sure that the requested selection is within the proper bounds + if( newsel >= pData->total_tabs ) + return( pData->selected_tab ); + + // make sure that the selection actually changed + if( newsel != pData->selected_tab ) + { + // set selection + pData->selected_tab = newsel; + + // make us redraw + InvalidateRect( hwnd, NULL, FALSE ); + UpdateWindow( hwnd ); + } + + return( pData->selected_tab ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_GetCurSel() +// +// Retrieves the current selection +// +// Input: +// hwnd - our window handle +// +// Returns: +// the current selection +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnGetCurSel( HWND hwnd ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // get selection + return( pData->selected_tab ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnGetItemCount() +// +// Retrieves the number of tabs currently in use +// +// Input: +// hwnd - our window handle +// +// Returns: +// the number of tabs in use +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +UINT BookTab_OnGetItemCount( HWND hwnd ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // get the number of tabs + return( pData->total_tabs ); +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnSetItemData() +// +// Adds a DWORD of data to the data structure for the given tab +// +// Input: +// hwnd - our window handle +// index - which tab to add data to +// data - what to add +// +// Returns: +// TRUE if succcessful, else FALSE +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL BookTab_OnSetItemData( HWND hwnd, UINT index, DWORD data ) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // set the instance data + pData->tab[index].data = data; + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnPutInBack() +// +// Sets the focus to the booktab and then back to whoever had it first, +// this seemes to put this control in the very back. +// +// Input: +// hwnd - our window handle +// +// Returns: +// +// +// History +// Arthur Brooking 1/21/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_OnPutInBack( HWND hwnd ) +{ + HWND hwndOldFocus; + + // set the focus to us + hwndOldFocus = SetFocus( hwnd ); + + // if there was an old focus, set it back to that. + if( hwndOldFocus ) + SetFocus( hwndOldFocus ); + +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_OnGetItemData() +// +// Gets the DWORD of data stored in the data structure for the given tab +// +// Input: +// hwnd - our window handle +// index - which tab to get data from +// +// Returns: +// the stored DWORD +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +DWORD BookTab_OnGetItemData( HWND hwnd, UINT index) +{ + LPTABDATA pData; + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // get the instance data + return( (DWORD)pData->tab[index].data ); +} + +////////////////////////////////////////////////////////////////////////////// +// IsPointInRect() +// +// determines if the point specifier is in the rectangle specified +// +// Input: +// given_x - x coordinate of the point to be tested +// given_y - y coordinate of the point to be tested +// pTab - a pointer to the rectangle to test against +// +// Returns: +// True if the point is within the rectangle, False if not +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +BOOL IsPointInRect( int given_x, int given_y, LPRECT pRect ) +{ + // is it above + if( given_y < pRect->top ) + return FALSE; + + // is it below + if( given_y > pRect->bottom ) + return FALSE; + + // is it to the left + if( given_x < pRect->left ) + return FALSE; + + // is it to the right + if( given_x > pRect->right ) + return FALSE; + + // well, it must be inside + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// BookTab_UpdateButtons() +// +// Takes the current data and updates the sizes of the tabs +// +// Input: +// hwnd - our window handle +// +// Returns: +// nuthin +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// +void BookTab_UpdateButtons( HWND hwnd ) +{ + LPTABDATA pData; + HDC hdc; + SIZE cur_size; + RECT total_rect; + WORD yWidth; + WORD xWidth; + UINT left; + UINT i; + HFONT hfOldFont; + + + // get the instance data + pData = GetInstanceDataPtr( hwnd ); + + // preset this so that the MAXes later will work + pData->tabs_rect.bottom = 0; + + xWidth = GetSystemMetrics(SM_CXBORDER); + yWidth = GetSystemMetrics(SM_CYBORDER); + GetClientRect( hwnd, &total_rect); + // BUGBUG cheat to see the whole thing + total_rect.bottom -= yWidth; + total_rect.right -= xWidth; + + hdc = GetDC( hwnd ); + + // use the selected font (BOLD) to size the tabs + hfOldFont = SelectObject( hdc, pData->hfSelected ); + + // loop thru the tabs + left = total_rect.left; + for( i = 0; i < pData->total_tabs; i++ ) + { + // get the size of the data for this tab + GetTextExtentPoint( hdc, pData->tab[i].label, + lstrlen( pData->tab[i].label), &cur_size); + + // calculate the text rectatangle first ... + // the text top is down the size of the angle + pData->tab[i].text_rect.top = total_rect.top + ANGLE_Y*yWidth; + + // the text left is over the size of the angle + pData->tab[i].text_rect.left = left + ANGLE_X*xWidth; + + // the text bottom is down from the top the size of the text + + // 2x the fluff(top and bottom) + 2x the carat space + pData->tab[i].text_rect.bottom = pData->tab[i].text_rect.top + + cur_size.cy + 2*FLUFF_Y*yWidth + 2*CARAT_Y*yWidth; + + // the text right is over from the left the size of the text + + // 2x the fluff(left and right) + 2x the carat space + pData->tab[i].text_rect.right = pData->tab[i].text_rect.left + + cur_size.cx + 2*FLUFF_X*xWidth + 2*CARAT_X*xWidth; + + + // then calculate the full tab rectangle + // the tab top is the top of the control + pData->tab[i].tab_rect.top = total_rect.top; + + // the left side of the tab is next to the previous right + pData->tab[i].tab_rect.left = left; + + // the tab bottom is down the footroom from the text bottom + pData->tab[i].tab_rect.bottom = pData->tab[i].text_rect.bottom + + FOOTROOM_Y*yWidth; + + // the tab right is over the size of the angle from the text right + pData->tab[i].tab_rect.right = pData->tab[i].text_rect.right + + ANGLE_Y*yWidth; + + // set the left for the next guy to be our right + left = pData->tab[i].tab_rect.right; + + // set the bottom of the all tabs rectangle + pData->tabs_rect.bottom = max( pData->tabs_rect.bottom, + pData->tab[i].tab_rect.bottom); + + // BUGBUG check for run off the side + } + + // set the rest of the cumulative tabs rect + pData->tabs_rect.top = total_rect.top; + pData->tabs_rect.right = total_rect.right; + pData->tabs_rect.left = total_rect.left; + // BUGBUG why + pData->tabs_rect.bottom++; + + // reset the font + SelectObject( hdc, hfOldFont ); + + // free up the resources used + ReleaseDC( hwnd, hdc ); +} + + + +////////////////////////////////////////////////////////////////////////////// +// BookTab_() +// +// +// +// Input: +// hwnd - our window handle +// +// Returns: +// +// +// History +// Arthur Brooking 8/06/93 created +////////////////////////////////////////////////////////////////////////////// + diff --git a/private/nw/convert/nwconv/tab.h b/private/nw/convert/nwconv/tab.h new file mode 100644 index 000000000..413c32623 --- /dev/null +++ b/private/nw/convert/nwconv/tab.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// Book Tab Control Name +////////////////////////////////////////////////////////////////////////////// +#define BOOK_TAB_CONTROL TEXT("BOOKTAB") + +////////////////////////////////////////////////////////////////////////////// +// Book Tab specific input messages +////////////////////////////////////////////////////////////////////////////// +// +// message wParam lParam return action +// ------- ------ ------ ------ ------ +// BT_ADDITEM -- pItem index adds tab at next avail. spot +// BT_INSERTITEM index pItem index adds a new item at index +// BT_DELETEITEM index -- deletes the tab at index +// BT_DELETEALLITEMS -- -- deletes all tabs +// BT_SETITEM index pItem succ/fail replaces text on tab +// BT_GETITEM index pItem succ/fail retrieves text on tab +// BT_SETCURSEL index -- succ/fail sets the current selection +// BT_GETCURSEL -- -- index +// BT_GETITEMCOUNT -- -- item count +// BT_SETITEMDATA index data succ/fail store a DWORD with a tab +// BT_GETITEMDATA index -- data retrieve the DWORD from a tab +// BT_PUTINBACK -- -- solves focus problem +// +// +#define BT_BASE WM_USER + 777 +#define BT_ADDITEM BT_BASE + 0 +#define BT_INSERTITEM BT_BASE + 1 +#define BT_DELETEITEM BT_BASE + 2 +#define BT_DELETEALLITEMS BT_BASE + 3 +#define BT_SETITEM BT_BASE + 4 +#define BT_GETITEM BT_BASE + 5 +#define BT_SETCURSEL BT_BASE + 6 +#define BT_GETCURSEL BT_BASE + 7 +#define BT_GETITEMCOUNT BT_BASE + 8 +#define BT_SETITEMDATA BT_BASE + 9 +#define BT_GETITEMDATA BT_BASE + 10 +#define BT_PUTINBACK BT_BASE + 11 + +////////////////////////////////////////////////////////////////////////////// +// Book Tab specific notification messages +////////////////////////////////////////////////////////////////////////////// +// message wParam lParam meaning +// ------- ------ ------ ------- +// BTN_SELCHANGE index my hwnd the current selection has changed +// (please note that this notfification WILL NOT BE +// SENT if the selection is changed by the +// BT_SETCURSEL message). +// +#define BTN_SELCHANGE BT_BASE + 100 + +////////////////////////////////////////////////////////////////////////////// +// Book Tab functions for all to see +////////////////////////////////////////////////////////////////////////////// +void BookTab_Initialize(HINSTANCE hInstance); + +////////////////////////////////////////////////////////////////////////////// +// Book Tab macros to make messages look like functions +////////////////////////////////////////////////////////////////////////////// +#define BookTab_AddItem(hwndCtl, text) ((UINT)(DWORD)SendMessage((hwndCtl), BT_ADDITEM, (WPARAM)(0), (LPARAM)(LPCTSTR)(text) )) +#define BookTab_InsertItem(hwndCtl, index, text) ((UINT)(DWORD)SendMessage((hwndCtl), BT_INSERTITEM, (WPARAM)(UINT)(index), (LPARAM)(LPCTSTR)(text) )) +#define BookTab_DeleteItem(hwndCtl, index) ((void)(DWORD)SendMessage((hwndCtl), BT_DELETEITEM, (WPARAM)(UINT)(index), (LPARAM)(0) )) +#define BookTab_DeleteAllItems(hwndCtl) ((void)(DWORD)SendMessage((hwndCtl), BT_DELETEALLITEMS, (WPARAM)(0), (LPARAM)(0) )) +#define BookTab_SetItem(hwndCtl, index, text) ((BOOL)(DWORD)SendMessage((hwndCtl), BT_SETITEM, (WPARAM)(UINT)(index), (LPARAM)(LPCTSTR)(text) )) +#define BookTab_GetItem(hwndCtl, index, text) ((BOOL)(DWORD)SendMessage((hwndCtl), BT_GETITEM, (WPARAM)(UINT)(index), (LPARAM)(LPCTSTR)(text) )) +#define BookTab_SetCurSel(hwndCtl, index) ((BOOL)(DWORD)SendMessage((hwndCtl), BT_SETCURSEL, (WPARAM)(UINT)(index), (LPARAM)(0) )) +#define BookTab_GetCurSel(hwndCtl) ((UINT)(DWORD)SendMessage((hwndCtl), BT_GETCURSEL, (WPARAM)(0), (LPARAM)(0) )) +#define BookTab_GetItemCount(hwndCtl) ((UINT)(DWORD)SendMessage((hwndCtl), BT_GETITEMCOUNT, (WPARAM)(0), (LPARAM)(0) )) +#define BookTab_SetItemData(hwndCtl, index, data) ((BOOL)(DWORD)SendMessage((hwndCtl), BT_SETITEMDATA, (WPARAM)(UINT)(index), (LPARAM)(DWORD)(data) )) +#define BookTab_GetItemData(hwndCtl, index) ((DWORD)(DWORD)SendMessage((hwndCtl), BT_GETITEMDATA, (WPARAM)(UINT)(index), (LPARAM)(0) )) +#define BookTab_PutInBack(hwndCtl) ((DWORD)(DWORD)PostMessage((hwndCtl), BT_PUTINBACK, (WPARAM)(0), (LPARAM)(0) )) diff --git a/private/nw/convert/nwconv/transfer.c b/private/nw/convert/nwconv/transfer.c new file mode 100644 index 000000000..94f5d4350 --- /dev/null +++ b/private/nw/convert/nwconv/transfer.c @@ -0,0 +1,2381 @@ +/* + +-------------------------------------------------------------------------+ + | Netware to Windows NT Transfer Loop | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [Transfer.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth June 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" + +#include +#include +#include +#include + +#include "nwconv.h" +#include "convapi.h" +#include "ntnetapi.h" +#include "nwnetapi.h" +#include "userdlg.h" +#include "statbox.h" +#include "filedlg.h" +#include "map.h" + +#define NWC_ERR_IGNORE 1 +#define NWC_ERR_NAMELONG 2 +#define NWC_ERR_DUPLICATE 3 +#define NWC_ERR_NAMEINVALID 4 + +#define ILLEGAL_CHARS TEXT("\"\\/[]:;=,+*?<>") + +// define for routines in fcopy.c +void ConvertFiles(HWND hDlg, BOOL TConversion, USER_LIST *Users, GROUP_LIST *Groups); +void ConvertFilesInit(HWND hDlg); +void VSharesCreate(DEST_SERVER_BUFFER *DServ, BOOL TConversion); + +// Cache of user and group lists +typedef struct _LIST_CACHE { + struct _LIST_CACHE *next; + ULONG Count; + void *ul; +} LIST_CACHE; + +static LIST_CACHE *UserCacheHead = NULL; +static LIST_CACHE *GroupCacheHead = NULL; + +// Misc string holders +static LPTSTR LocalName = NULL; +static LPTSTR SourceServer, DestServer; +TCHAR UserServerName[MAX_SERVER_NAME_LEN + 3]; +static TCHAR tmpStr[80]; +static TCHAR tmpStr2[60]; +static TCHAR ErrorText[256]; +static TCHAR NewName[256]; +static TCHAR pLine[256]; + +static CONVERT_OPTIONS *ConvOpt = NULL; +static FILE_OPTIONS *FileOptions = NULL; +static BOOL TConversion; +static BOOL WarningDlgForNTFS; + +// Totals for stat box +static UINT TotErrors; +static UINT TotGroups; +static UINT TotUsers; +static UINT TotConversions; +UINT TotFiles; +ULONG StartTime; +ULONG CurrTime; + +// User and Group list pointers +static USER_LIST *Users = NULL; +static USER_LIST *NTUsers = NULL; +static GROUP_LIST *Groups = NULL; +static GROUP_LIST *NTGroups = NULL; +static DWORD UserCount, NTUserCount; +static DWORD GroupCount, NTGroupCount; +static BOOL TransferCancel = FALSE; + +static MAP_FILE *hMap; + +// All of this is used for transfer lists in the conversion +#define USER_SERVER 0 +#define USER_SERVER_PDC 1 +#define USER_SERVER_TRUSTED 2 + +typedef struct _TRANSFER_BUFFER { + LPTSTR ServerName; + UINT UserServerType; + CONVERT_LIST *ConvertList; +} TRANSFER_BUFFER; + +typedef struct _TRANSFER_LIST { + ULONG Count; + TRANSFER_BUFFER TList[]; +} TRANSFER_LIST; + + +/*+-------------------------------------------------------------------------+ + | ErrorIt() + | + +-------------------------------------------------------------------------+*/ +void ErrorIt(LPTSTR szFormat, ...) { + static TCHAR tmpStr[1024]; + va_list marker; + + va_start(marker, szFormat); + + wvsprintf(tmpStr, szFormat, marker); +#ifdef DEBUG + dprintf(TEXT("Errorit: %s\n"), tmpStr); +#endif + + TotErrors++; + Status_TotErrors(TotErrors); + LogWriteErr(TEXT("%s"),tmpStr); + va_end(marker); + +} // ErrorIt + + +/*+-------------------------------------------------------------------------+ + | NTFS Check Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ShareListNTFSCheck() + | + +-------------------------------------------------------------------------+*/ +BOOL ShareListNTFSCheck() { + CONVERT_LIST *ConvList; + DEST_SERVER_BUFFER *DServ; + SOURCE_SERVER_BUFFER *SServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *Drive; + ULONG i; + FILE_OPTIONS *FileOptions; + + // Go through the convert list checking for any shares to non NTFS drives + ConvList = ConvertListStart; + + while (ConvList != NULL) { + DServ = ConvList->FileServ; + SServ = ConvList->SourceServ; + + FileOptions = (FILE_OPTIONS *) ConvList->FileOptions; + if (FileOptions->TransferFileInfo) { + ShareList = SServ->ShareList; + + if (ShareList != NULL) { + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + + // if not flagged as okay for going to fat, then must check + if (SList[i].Convert && !SList[i].ToFat) + if (SList[i].DestShare != NULL) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + Drive = VShare->Drive; + + if ((Drive == NULL) || (Drive->Type != DRIVE_TYPE_NTFS)) + return FALSE; + } else { + Drive = SList[i].DestShare->Drive; + + if ((Drive == NULL) || (Drive->Type != DRIVE_TYPE_NTFS)) + return FALSE; + } + } // for loop through shares + + } + + } // if FileOptions + + ConvList = ConvList->next; + } + + return TRUE; + +} // ShareListNTFSCheck + + +/*+-------------------------------------------------------------------------+ + | ShareListNTFSListboxFill() + | + +-------------------------------------------------------------------------+*/ +void ShareListNTFSListboxFill(HWND hDlg) { + TCHAR AddLine[256]; + CONVERT_LIST *ConvList; + DEST_SERVER_BUFFER *DServ; + SOURCE_SERVER_BUFFER *SServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *Drive; + ULONG i; + HWND hCtrl; + FILE_OPTIONS *FileOptions; + + // Go through the convert list checking for any shares to non NTFS drives + ConvList = ConvertListStart; + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + + while (ConvList != NULL) { + DServ = ConvList->FileServ; + SServ = ConvList->SourceServ; + + FileOptions = (FILE_OPTIONS *) ConvList->FileOptions; + if (FileOptions->TransferFileInfo) { + ShareList = SServ->ShareList; + + if (ShareList != NULL) { + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + + // if not flagged as okay for going to fat, then must check + if (SList[i].Convert && !SList[i].ToFat) + if (SList[i].DestShare != NULL) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + Drive = VShare->Drive; + + if ((Drive == NULL) || (Drive->Type != DRIVE_TYPE_NTFS)) { + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, VShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } else { + Drive = SList[i].DestShare->Drive; + + if ((Drive == NULL) || (Drive->Type != DRIVE_TYPE_NTFS)) { + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, SList[i].DestShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } + } // for loop through shares + + } + } // if FileOptions + + ConvList = ConvList->next; + } + +} // ShareListNTFSListboxFill + + +/*+-------------------------------------------------------------------------+ + | ShareListFATOK() + | + +-------------------------------------------------------------------------+*/ +void ShareListFATOK() { + CONVERT_LIST *ConvList; + DEST_SERVER_BUFFER *DServ; + SOURCE_SERVER_BUFFER *SServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + ULONG i; + FILE_OPTIONS *FileOptions; + + // Go through the convert list checking for any shares to non NTFS drives + ConvList = ConvertListStart; + + while (ConvList != NULL) { + DServ = ConvList->FileServ; + SServ = ConvList->SourceServ; + + FileOptions = (FILE_OPTIONS *) ConvList->FileOptions; + if (FileOptions->TransferFileInfo) { + ShareList = SServ->ShareList; + + if (ShareList != NULL) { + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + if (SList[i].Convert) + SList[i].ToFat = TRUE; + } + + } + } // if FileOptions + + ConvList = ConvList->next; + } + +} // ShareListFATOK + + +/*+-------------------------------------------------------------------------+ + | Space Check Routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ShareListSpaceCheck() + | + +-------------------------------------------------------------------------+*/ +BOOL ShareListSpaceCheck() { + CONVERT_LIST *ConvList; + DEST_SERVER_BUFFER *DServ; + SOURCE_SERVER_BUFFER *SServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *Drive; + ULONG i; + FILE_OPTIONS *FileOptions; + + // Go through the convert list checking for any shares to non NTFS drives + ConvList = ConvertListStart; + + while (ConvList != NULL) { + DServ = ConvList->FileServ; + SServ = ConvList->SourceServ; + + FileOptions = (FILE_OPTIONS *) ConvList->FileOptions; + if (FileOptions->TransferFileInfo) { + ShareList = SServ->ShareList; + + if (ShareList != NULL) { + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + + if (SList[i].Convert && (SList[i].DestShare != NULL)) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + Drive = VShare->Drive; + + if ((Drive == NULL) || (Drive->AllocSpace > Drive->FreeSpace)) + return FALSE; + } else { + Drive = SList[i].DestShare->Drive; + + if ((Drive == NULL) || (Drive->AllocSpace > Drive->FreeSpace)) + return FALSE; + } + } // for loop through shares + + } + } // if FileOptions + + ConvList = ConvList->next; + } + + return TRUE; + +} // ShareListSpaceCheck + + +/*+-------------------------------------------------------------------------+ + | ShareListSpaceListboxFill() + | + +-------------------------------------------------------------------------+*/ +void ShareListSpaceListboxFill(HWND hDlg) { + TCHAR AddLine[256]; + TCHAR Free[25]; + CONVERT_LIST *ConvList; + DEST_SERVER_BUFFER *DServ; + SOURCE_SERVER_BUFFER *SServ; + SHARE_LIST *ShareList; + SHARE_BUFFER *SList; + VIRTUAL_SHARE_BUFFER *VShare; + DRIVE_BUFFER *Drive; + ULONG i; + HWND hCtrl; + FILE_OPTIONS *FileOptions; + + // Go through the convert list checking for any shares to non NTFS drives + ConvList = ConvertListStart; + hCtrl = GetDlgItem(hDlg, IDC_LIST1); + + while (ConvList != NULL) { + DServ = ConvList->FileServ; + SServ = ConvList->SourceServ; + + FileOptions = (FILE_OPTIONS *) ConvList->FileOptions; + if (FileOptions->TransferFileInfo) { + ShareList = SServ->ShareList; + + if (ShareList != NULL) { + + SList = ShareList->SList; + for (i = 0; i < ShareList->Count; i++) { + + if (SList[i].Convert && (SList[i].DestShare != NULL)) + if (SList[i].Virtual) { + VShare = (VIRTUAL_SHARE_BUFFER *) SList[i].DestShare; + Drive = VShare->Drive; + + if (Drive != NULL) { + if (Drive->AllocSpace > Drive->FreeSpace) { + // List shares then space + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, VShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + + lstrcpy(Free, lToStr(Drive->FreeSpace)); + wsprintf(AddLine, Lids(IDS_D_13), Free, lToStr(Drive->AllocSpace)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } else { + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, VShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + + wsprintf(AddLine, Lids(IDS_D_14)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } else { + Drive = SList[i].DestShare->Drive; + + if (Drive != NULL) { + if (Drive->AllocSpace > Drive->FreeSpace) { + // List shares then space + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, SList[i].DestShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + + lstrcpy(Free, lToStr(Drive->FreeSpace)); + wsprintf(AddLine, Lids(IDS_D_13), Free, lToStr(Drive->AllocSpace)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } else { + wsprintf(AddLine, TEXT("%s\\%s: -> \\\\%s\\%s"), SServ->Name, SList[i].Name, DServ->Name, SList[i].DestShare->Name); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + + wsprintf(AddLine, Lids(IDS_D_14)); + SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) AddLine); + } + } // if Virtual + + } // for loop through shares + + } + } // if FileOptions + + ConvList = ConvList->next; + } + +} // ShareListSpaceListboxFill + + +/*+-------------------------------------------------------------------------+ + | Conversion Warning Dialog | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | DlgConversionWarning() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgConversionWarning(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + int wmId, wmEvent; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + if (WarningDlgForNTFS) { + SendDlgItemMessage(hDlg, IDC_PANEL1, WM_SETTEXT, 0, (LPARAM) Lids(IDS_D_15)); + ShareListNTFSListboxFill(hDlg); + } else { + SendDlgItemMessage(hDlg, IDC_PANEL1, WM_SETTEXT, 0, (LPARAM) Lids(IDS_D_16)); + ShareListSpaceListboxFill(hDlg); + } + + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDYES: + if (WarningDlgForNTFS) + ShareListFATOK(); + + EndDialog(hDlg, 0); + return (TRUE); + break; + + case IDNO: + TransferCancel = TRUE; + EndDialog(hDlg, 0); + return (TRUE); + break; + + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgConversionWarning + + +/*+-------------------------------------------------------------------------+ + | ConversionWarningDlg_Do() + | + +-------------------------------------------------------------------------+*/ +void ConversionWarningDlg_Do(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC) DlgConversionWarning, hInst); + DialogBox(hInst, TEXT("AlertSel"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // ConversionWarningDlg_Do + + +/*+-------------------------------------------------------------------------+ + | NTFSCheck() + | + +-------------------------------------------------------------------------+*/ +void NTFSCheck(HWND hDlg) { + WarningDlgForNTFS = TRUE; + + if (!ShareListNTFSCheck()) + ConversionWarningDlg_Do(hDlg); + +} // NTFSCheck + + +/*+-------------------------------------------------------------------------+ + | SpaceCheck() + | + +-------------------------------------------------------------------------+*/ +void SpaceCheck(HWND hDlg) { + WarningDlgForNTFS = FALSE; + + if (!ShareListSpaceCheck()) + ConversionWarningDlg_Do(hDlg); + +} // SpaceCheck + + + +/*+-------------------------------------------------------------------------+ + | End of Conversion Dialog | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | DlgConversionEnd() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgConversionEnd(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HANDLE hFile; + int wmId, wmEvent; + static char CmdLine[256]; + HWND hCtrl; + + switch (message) { + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + hCtrl = GetDlgItem(hDlg, IDC_VIEWLOG); + + // check if logfile exists, if it does allow log file viewing... + hFile = CreateFileA( "LogFile.LOG", GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile != (HANDLE) INVALID_HANDLE_VALUE) + CloseHandle( hFile ); + else + EnableWindow(hCtrl, FALSE); + + SendDlgItemMessage(hDlg, IDC_S_TOT_COMP, WM_SETTEXT, 0, (LPARAM) lToStr(TotConversions)); + SendDlgItemMessage(hDlg, IDC_S_TOT_GROUPS, WM_SETTEXT, 0, (LPARAM) lToStr(TotGroups)); + SendDlgItemMessage(hDlg, IDC_S_TOT_USERS, WM_SETTEXT, 0, (LPARAM) lToStr(TotUsers)); + SendDlgItemMessage(hDlg, IDC_S_TOT_FILES, WM_SETTEXT, 0, (LPARAM) lToStr(TotFiles)); + SendDlgItemMessage(hDlg, IDC_S_TOT_ERRORS, WM_SETTEXT, 0, (LPARAM) lToStr(TotErrors)); + + if (TransferCancel) + SendMessage(hDlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) Lids(IDS_D_17)); + + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + case IDCANCEL: + EndDialog(hDlg, 0); + return (TRUE); + break; + + case IDC_VIEWLOG: + lstrcpyA(CmdLine, "LogView "); + lstrcatA(CmdLine, "Error.LOG Summary.LOG LogFile.LOG"); + WinExec(CmdLine, SW_SHOW); + return (TRUE); + break; + + } + + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgConversionEnd + + +/*+-------------------------------------------------------------------------+ + | ConversionEndDlg_Do() + | + +-------------------------------------------------------------------------+*/ +void ConversionEndDlg_Do(HWND hDlg) { + DLGPROC lpfnDlg; + + lpfnDlg = MakeProcInstance((DLGPROC) DlgConversionEnd, hInst); + DialogBox(hInst, TEXT("ConversionEnd"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); + +} // ConversionEndDlg_Do + + + +/*+-------------------------------------------------------------------------+ + | User / Group lists and Cache routines | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | FindUserMatch() + | + | Searches through the user list using a binary search. Returns a + | pointer to the found user record or NULL if no match. + | + +-------------------------------------------------------------------------+*/ +USER_BUFFER *FindUserMatch(LPTSTR Name, USER_LIST *UserList, BOOL NewName) { + LONG begin = 0; + LONG end; + LONG cur; + int match; + USER_BUFFER *UserBuffer; + + if (UserList == NULL) + return NULL; + + UserBuffer = UserList->UserBuffer; + end = UserList->Count - 1; + + while (end >= begin) { + // go halfway in-between + cur = (begin + end) / 2; + + // compare the two result into match + if (NewName) + match = lstrcmpi(Name, UserBuffer[cur].NewName); + else + match = lstrcmpi(Name, UserBuffer[cur].Name); + + if (match < 0) + // move new begin + end = cur - 1; + else + begin = cur + 1; + + if (match == 0) + return &UserBuffer[cur]; + } + + return NULL; + +} // FindUserMatch + + +/*+-------------------------------------------------------------------------+ + | FindGroupMatch() + | + | Searches through the group list using a binary search. Returns a + | pointer to the found group record or NULL if no match. + | + +-------------------------------------------------------------------------+*/ +GROUP_BUFFER *FindGroupMatch(LPTSTR Name, GROUP_LIST *GroupList, BOOL NewName) { + LONG begin = 0; + LONG end; + LONG cur; + int match; + GROUP_BUFFER *GroupBuffer; + + if (GroupList == NULL) + return NULL; + + GroupBuffer = GroupList->GroupBuffer; + end = GroupList->Count - 1; + + while (end >= begin) { + // go halfway in-between + cur = (begin + end) / 2; + + // compare the two result into match + if (NewName) + match = lstrcmpi(Name, GroupBuffer[cur].NewName); + else + match = lstrcmpi(Name, GroupBuffer[cur].Name); + + if (match < 0) + // move new begin + end = cur - 1; + else + begin = cur + 1; + + if (match == 0) + return &GroupBuffer[cur]; + } + + return NULL; + +} // FindGroupMatch + + +/*+-------------------------------------------------------------------------+ + | The List Cache's are a linked list of previously converted user and + | group lists. This is mostly for when running trial conversions you can + | check if a previously transferred name conflicts with a new name (since + | the name won't actually be out on the destination server). + | + | The Cache is kept around while working with the same destination server + | or domain. Once a new domain/server is selected the cache and all lists + | should be freed. + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ListCachePut() + | + +-------------------------------------------------------------------------+*/ +BOOL ListCachePut(LIST_CACHE **CacheHead, void *ul, ULONG Count) { + LIST_CACHE *cc; + LIST_CACHE *pc; + + cc = (LIST_CACHE *) AllocMemory(sizeof(LIST_CACHE)); + + if (cc == NULL) + return FALSE; + + // Init the cache entry + cc->next = NULL; + cc->Count = Count; + cc->ul = ul; + + // Now put it at the end of the chain + if (*CacheHead == NULL) { + *CacheHead = cc; + return TRUE; + } + + pc = *CacheHead; + while (pc->next) + pc = pc->next; + + pc->next = cc; + return TRUE; + +} // ListCachePut + + +/*+-------------------------------------------------------------------------+ + | ListCacheFree() + | + +-------------------------------------------------------------------------+*/ +void ListCacheFree(LIST_CACHE **CacheHead) { + LIST_CACHE *cc; + LIST_CACHE *pc; + + cc = *CacheHead; + + while (cc) { + // Free the user list attached to this cache entry + FreeMemory(cc->ul); + + // Save next cache entry + pc = cc->next; + + // Free up the cache entry and loop + FreeMemory(cc); + cc = pc; + } + + *CacheHead = NULL; + +} // ListCacheFree + + +/*+-------------------------------------------------------------------------+ + | UserCacheMatch() + | + +-------------------------------------------------------------------------+*/ +BOOL UserCacheMatch(LPTSTR UserName) { + LIST_CACHE *cc; + BOOL match = FALSE; + + cc = UserCacheHead; + + // loop through the cache entries and try to match with each user list + while (cc && !match) { + if (FindUserMatch(UserName, (USER_LIST *) cc->ul, TRUE)) + match = TRUE; + else + cc = cc->next; + } + + return match; + +} // UserCacheMatch + + +/*+-------------------------------------------------------------------------+ + | GroupCacheMatch() + | + +-------------------------------------------------------------------------+*/ +BOOL GroupCacheMatch(LPTSTR GroupName) { + LIST_CACHE *cc; + BOOL match = FALSE; + + cc = GroupCacheHead; + + // loop through the cache entries and try to match with each user list + while (cc && !match) { + if (FindGroupMatch(GroupName, (GROUP_LIST *) cc->ul, TRUE)) + match = TRUE; + else + cc = cc->next; + } + + return match; + +} // GroupCacheMatch + + +/*+-------------------------------------------------------------------------+ + | Logging Garbage | + +-------------------------------------------------------------------------+*/ + +/*+-------------------------------------------------------------------------+ + | ConvertOptionsLog() + | + | Writes all the admin selected conversion options to the log file. + | + +-------------------------------------------------------------------------+*/ +void ConvertOptionsLog() { + + LogWriteLog(0, Lids(IDS_L_136)); + + if (ConvOpt->TransferUserInfo) + LogWriteLog(1, Lids(IDS_L_137), Lids(IDS_YES)); + else + LogWriteLog(1, Lids(IDS_L_137), Lids(IDS_NO)); + + LogWriteLog(0, Lids(IDS_CRLF)); + + if (ConvOpt->TransferUserInfo) { + LogWriteLog(1, Lids(IDS_L_140)); + + if (ConvOpt->UseMappingFile) { + LogWriteLog(2, Lids(IDS_L_138), Lids(IDS_YES)); + LogWriteLog(3, Lids(IDS_L_139), ConvOpt->MappingFile); + } else { + LogWriteLog(2, Lids(IDS_L_138), Lids(IDS_NO)); + + // Password Options + LogWriteLog(2, Lids(IDS_L_141)); + switch (ConvOpt->PasswordOption) { + case 0: // Use NULL + LogWriteLog(0, Lids(IDS_L_142)); + break; + + case 1: // Password is username + LogWriteLog(0, Lids(IDS_L_143)); + break; + + case 2: // Use constant + LogWriteLog(0, Lids(IDS_L_144), ConvOpt->PasswordConstant); + break; + } + } + + if (ConvOpt->ForcePasswordChange) + LogWriteLog(3, Lids(IDS_L_145), Lids(IDS_YES)); + else + LogWriteLog(3, Lids(IDS_L_145), Lids(IDS_NO)); + + if (!ConvOpt->UseMappingFile) { + // User Names Options + LogWriteLog(2, Lids(IDS_L_146)); + + switch (ConvOpt->UserNameOption) { + case 0: // Don't transfer - log failures + LogWriteLog(0, Lids(IDS_L_148)); + break; + + case 1: // Ignore + LogWriteLog(0, Lids(IDS_L_149)); + break; + + case 2: // Overwrite with new info + LogWriteLog(0, Lids(IDS_L_151)); + break; + + case 3: // Pre-Pend constant + LogWriteLog(0, Lids(IDS_L_150), ConvOpt->UserConstant); + break; + } + + LogWriteLog(0, Lids(IDS_CRLF)); + + // Group Names Options + LogWriteLog(2, Lids(IDS_L_147)); + + switch (ConvOpt->GroupNameOption) { + case 0: // Don't transfer - log failures + LogWriteLog(0, Lids(IDS_L_148)); + break; + + case 1: // Overwrite with new info + LogWriteLog(0, Lids(IDS_L_149)); + break; + + case 2: // Pre-Pend constant + LogWriteLog(0, Lids(IDS_L_150), ConvOpt->GroupConstant); + break; + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } + + if (ConvOpt->SupervisorDefaults) + LogWriteLog(2, Lids(IDS_L_152), Lids(IDS_YES)); + else + LogWriteLog(2, Lids(IDS_L_152), Lids(IDS_NO)); + + if (ConvOpt->AdminAccounts) + LogWriteLog(2, Lids(IDS_L_153), Lids(IDS_YES)); + else + LogWriteLog(2, Lids(IDS_L_153), Lids(IDS_NO)); + + if (ConvOpt->UseTrustedDomain && (ConvOpt->TrustedDomain != NULL)) + LogWriteLog(2, Lids(IDS_L_154), ConvOpt->TrustedDomain->Name); + + LogWriteLog(0, Lids(IDS_CRLF)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + +} // ConvertOptionsLog + + +/*+-------------------------------------------------------------------------+ + | OptionsFileLog() + | + +-------------------------------------------------------------------------+*/ +void OptionsFileLog() { + LogWriteLog(0, Lids(IDS_L_155)); + + if (FileOptions->TransferFileInfo) + LogWriteLog(1, Lids(IDS_L_156), Lids(IDS_YES)); + else + LogWriteLog(1, Lids(IDS_L_156), Lids(IDS_NO)); + + LogWriteLog(0, Lids(IDS_CRLF)); +} // OptionsFileLog + + +/*+-------------------------------------------------------------------------+ + | ConvertPairLog() + | + +-------------------------------------------------------------------------+*/ +void ConvertPairLog() { + LogWriteLog(0, Lids(IDS_LINE)); + wsprintf(tmpStr, Lids(IDS_L_157), SourceServer); + LogWriteLog(0, Lids(IDS_BRACE), tmpStr); + + wsprintf(tmpStr, Lids(IDS_L_158), DestServer); + LogWriteLog(0, Lids(IDS_BRACE), tmpStr); + + LogWriteLog(0, Lids(IDS_LINE)); + GetTime(tmpStr2); + wsprintf(tmpStr, Lids(IDS_L_159), tmpStr2); + LogWriteLog(0, Lids(IDS_BRACE), tmpStr); + LogWriteLog(0, Lids(IDS_LINE)); + LogWriteLog(0, Lids(IDS_CRLF)); + + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteSummary(0, TEXT("[%s -> %s]\r\n"), SourceServer, DestServer); + ErrorContextSet(TEXT("[%s -> %s]\r\n"), SourceServer, DestServer); + +} // ConvertPairLog + + +/*+-------------------------------------------------------------------------+ + | UsersLogNames() + | + +-------------------------------------------------------------------------+*/ +void UsersLogNames(USER_LIST *Users) { + ULONG i; + DWORD UserCount; + USER_BUFFER *UserBuffer; + + if (Users == NULL) + return; + + UserCount = Users->Count; + UserBuffer = Users->UserBuffer; + + if (UserCount) { + LogWriteLog(1, Lids(IDS_L_160)); + LogWriteLog(1, Lids(IDS_L_161)); + + // Check Mapping File + for (i = 0; i < UserCount; i++) { + if (UserBuffer[i].IsNewName) + wsprintf(pLine, TEXT("%s -> %s"), UserBuffer[i].Name, UserBuffer[i].NewName); + else + wsprintf(pLine, TEXT("%s"), UserBuffer[i].NewName); + + LogWriteLog(1, TEXT(" %-50s"), pLine); + + if (UserBuffer[i].err) { + if (UserBuffer[i].err == NWC_ERR_NAMELONG) + LogWriteLog(0, Lids(IDS_L_162)); + + if (UserBuffer[i].err == NWC_ERR_DUPLICATE) + LogWriteLog(0, Lids(IDS_L_163)); + + if (UserBuffer[i].err == NWC_ERR_NAMEINVALID) + LogWriteLog(0, Lids(IDS_L_164)); + + } + + // Need to check this seperatly - as it's not an error + if (UserBuffer[i].Overwrite) + LogWriteLog(0, Lids(IDS_L_163)); + + LogWriteLog(0, Lids(IDS_CRLF)); + + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } + +} // UsersLogNames + + +/*+-------------------------------------------------------------------------+ + | UserNewName_Check() + | + +-------------------------------------------------------------------------+*/ +void UserNewName_Check(USER_BUFFER *Users) { + // We have done any mappings that need to be done, now check for + // name validity if there is a new name... + if (Users->IsNewName) + if (UserCacheMatch(Users->NewName)) { + Users->err = NWC_ERR_DUPLICATE; + } + + if (lstrlen(Users->NewName) > MAX_NT_USER_NAME_LEN) { + // Name is too long + Users->err = NWC_ERR_NAMELONG; + } + + // Check if a valid name (no illegal characters)... + if ((int) wcscspn(Users->NewName, ILLEGAL_CHARS) < (int) lstrlen(Users->NewName)) + Users->err = NWC_ERR_NAMEINVALID; + +} // UserNewName_Check + + +/*+-------------------------------------------------------------------------+ + | UserNames_Resolve() + | + +-------------------------------------------------------------------------+*/ +void UserNames_Resolve(USER_BUFFER *Users) { + LPTSTR TheName; + LPTSTR ErrorText; + ULONG RetType; + + // Figure out which name to use + if (Users->IsNewName) + TheName = Users->Name; + else + TheName = Users->NewName; + + // If using mapping file then map the name appropriatly + if (ConvOpt->UseMappingFile) { + if (UserCacheMatch(TheName)) + Users->err = NWC_ERR_DUPLICATE; + } else { + // check if the user name is in the destination list (duplicate) + if (UserCacheMatch(TheName)) { + // There was - so figure out based on conversion options what + // to do with it... + switch (ConvOpt->UserNameOption) { + case 0: // Log Errors + Users->err = NWC_ERR_DUPLICATE; + break; + + case 1: // ignore + Users->err = NWC_ERR_IGNORE; + break; + + case 2: // Overwrite + Users->Overwrite = TRUE; + break; + + case 3: // Pre-Pend constant + lstrcpy(NewName, ConvOpt->UserConstant); + lstrcat(NewName, Users->Name); + lstrcpy(Users->NewName, NewName); + Users->IsNewName = TRUE; + break; + } // switch + } + } + + do { + RetType = IDIGNORE; + UserNewName_Check(Users); + + if (Users->err && (Users->err != NWC_ERR_IGNORE) && PopupOnError()) { + switch(Users->err) { + case NWC_ERR_NAMELONG: + ErrorText = Lids(IDS_L_165); + break; + + case NWC_ERR_DUPLICATE: + ErrorText = Lids(IDS_L_166); + break; + + case NWC_ERR_NAMEINVALID: + ErrorText = Lids(IDS_L_167); + break; + + } + + RetType = UserNameErrorDlg_Do(Lids(IDS_L_168), ErrorText, Users); + } + } while (RetType == IDRETRY); + + if (RetType == IDABORT) + TransferCancel = TRUE; + +} // UserNames_Resolve + + +/*+-------------------------------------------------------------------------+ + | UserSave() + | + | Given a user-name, moves their account information from the source + | to the destination server. + | + +-------------------------------------------------------------------------+*/ +BOOL UserSave(BOOL *NWInfo, LPTSTR origUserName, LPTSTR newUserName, NT_USER_INFO *NTInfo, void **OldInfo, BOOL Replace) { + NET_API_STATUS ret = 0; + void *NWUInfo; + FPNW_INFO fpnw; + static TCHAR ServerName[MAX_SERVER_NAME_LEN+3]; // +3 for leading slashes and ending NULL + + *NWInfo = FALSE; + + // Overlay NetWare info into record + NWUserInfoGet(origUserName, OldInfo); + NWUInfo = *OldInfo; + + if (NWUInfo == NULL) + return FALSE; + + *NWInfo = TRUE; + NWNetUserMapInfo(origUserName, NWUInfo, NTInfo); + + // Force user to change password if required + if (ConvOpt->ForcePasswordChange) + NTInfo->password_expired = (DWORD) (-1L); + + // Now get/map special FPNW info + if (ConvOpt->NetWareInfo) { + NWFPNWMapInfo(NWUInfo, &fpnw); + } + + if (!TConversion) + if (Replace) + if (ConvOpt->NetWareInfo) + ret = NTUserInfoSet(NTInfo, &fpnw); + else + ret = NTUserInfoSet(NTInfo, NULL); + else + if (ConvOpt->NetWareInfo) + ret = NTUserInfoSave(NTInfo, &fpnw); + else + ret = NTUserInfoSave(NTInfo, NULL); + + if (ret) + return FALSE; + else { + // now save out FPNW Info + if (ConvOpt->NetWareInfo) + NTSAMParmsSet(newUserName, fpnw, NTInfo->password, ConvOpt->ForcePasswordChange); + + return TRUE; + } + +} // UserSave + + +/*+-------------------------------------------------------------------------+ + | UsersConvert() + | + +-------------------------------------------------------------------------+*/ +void UsersConvert() { + static TCHAR Password[MAX_PW_LEN + 1]; + USER_BUFFER *UserBuffer = NULL; + BOOL NWInfo; + DWORD status = 0; + DWORD i; + void *NW_UInfo; + static NT_USER_INFO NT_UInfo; + ULONG TotConv = 0; + + Status_ConvTxt(Lids(IDS_D_18)); + Status_ItemLabel(Lids(IDS_D_19)); + + Status_CurTot((UINT) UserCount); + + LogWriteLog(0, Lids(IDS_L_169)); + LogWriteLog(1, Lids(IDS_L_170), UserCount); + ErrorCategorySet(Lids(IDS_L_171)); + + if (Users == NULL) + return; + + UserBuffer = Users->UserBuffer; + + // This will update the status pane - but we will reset it afterwards + for (i = 0; i < UserCount; i++) { + // Don't update totals yet, but update item ref incase this takes + // awhile + Status_CurNum((UINT) i + 1); + Status_Item(UserBuffer[i].Name); + + UserNames_Resolve(&UserBuffer[i]); + if (TransferCancel) + return; + } + + UsersLogNames(Users); + + i = 0; + while (i < UserCount) { + Status_CurNum((UINT) i + 1); + Status_Item(UserBuffer[i].Name); + lstrcpy(pLine, UserBuffer[i].Name); + + if (UserBuffer[i].IsNewName) + wsprintf(pLine, TEXT("[%s -> %s]"), UserBuffer[i].Name, UserBuffer[i].NewName); + else + wsprintf(pLine, TEXT("[%s]"), UserBuffer[i].NewName); + + LogWriteLog(1, TEXT("%-50s"), pLine); + ErrorItemSet(TEXT("%s\r\n"), pLine); + + // If duplicate or other type error just do logging - don't try to save + if (UserBuffer[i].err) { + if (UserBuffer[i].err == NWC_ERR_DUPLICATE) { + LogWriteLog(0, Lids(IDS_L_172)); + ErrorIt(Lids(IDS_L_173)); + } + + if (UserBuffer[i].err == NWC_ERR_NAMELONG) { + LogWriteLog(0, Lids(IDS_L_174)); + ErrorIt(Lids(IDS_L_175)); + } + + if (UserBuffer[i].err == NWC_ERR_NAMEINVALID) { + LogWriteLog(0, Lids(IDS_L_176)); + ErrorIt(Lids(IDS_L_177)); + } + + } else { + // Init the user record + NTUserRecInit(UserBuffer[i].NewName, &NT_UInfo); + + // +-------------------------------------------------------------+ + // | User name figured out - now map password | + // +-------------------------------------------------------------+ + memset(Password, 0, sizeof(Password)); + if (ConvOpt->UseMappingFile) + // If using map file, password is already set + lstrcpy(Password, UserBuffer[i].Password); + else + if (lstrlen(Password) == 0) { + // Didn't map password - so find what to use + switch (ConvOpt->PasswordOption) { + case 0: // No Password + // Don't need to do anything + break; + + case 1: // Username + // BUGBUG: Name can be longer then password!!! + lstrcpy(Password, UserBuffer[i].NewName); + break; + + case 2: // Constant + lstrcpy(Password, ConvOpt->PasswordConstant); + break; + + } // switch + } + + NT_UInfo.password = Password; + +#ifdef DEBUG +dprintf(TEXT("User: %s\n"), UserBuffer[i].Name); +#endif + + if (!UserSave(&NWInfo, UserBuffer[i].Name, UserBuffer[i].NewName, &NT_UInfo, &NW_UInfo, UserBuffer[i].Overwrite )) { + LogWriteLog(0, Lids(IDS_L_178)); + ErrorIt(Lids(IDS_L_179)); + } else { + // only increment total if actually converted... + TotUsers++; + TotConv++; + Status_TotUsers(TotUsers); + + LogWriteLog(0, Lids(IDS_L_180)); + LogWriteLog(0, Lids(IDS_CRLF)); + + // Converted - now need to save info to logs... + if (NWInfo) { + if (VerboseUserLogging()) + NWUserInfoLog(UserBuffer[i].Name, NW_UInfo); + + if (VerboseUserLogging()) + NTUserRecLog(NT_UInfo); + } + + } + + LogWriteLog(0, Lids(IDS_CRLF)); + + } + + i++; + } + + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteSummary(1, Lids(IDS_L_181), lToStr(TotConv)); + +} // UsersConvert + + +/*+-------------------------------------------------------------------------+ + | GroupSave() + | + +-------------------------------------------------------------------------+*/ +BOOL GroupSave(LPTSTR Name, DWORD *Status) { + + *Status = 0; + + if (!TConversion) + if ((*Status = NTGroupSave(Name))) + return FALSE; + + return TRUE; + +} // GroupSave + + +/*+-------------------------------------------------------------------------+ + | GroupNewName_Check() + | + +-------------------------------------------------------------------------+*/ +void GroupNewName_Check(GROUP_BUFFER *Groups) { + // We have done any mappings that need to be done, now check for + // name validity if there is a new name... + if (Groups->IsNewName) + if (GroupCacheMatch(Groups->NewName)) { + Groups->err = NWC_ERR_DUPLICATE; + } + + // make sure not too long + if (lstrlen(Groups->NewName) > MAX_NT_GROUP_NAME_LEN) { + // Name is too long + Groups->err = NWC_ERR_NAMELONG; + } + + // Check if a valid name (no illegal characters)... + if ((int) wcscspn(Groups->NewName, ILLEGAL_CHARS) < (int) lstrlen(Groups->NewName)) + Groups->err = NWC_ERR_NAMEINVALID; + +} // GroupNewName_Check + + +/*+-------------------------------------------------------------------------+ + | GroupNames_Resolve() + | + +-------------------------------------------------------------------------+*/ +void GroupNames_Resolve(GROUP_BUFFER *Groups) { + LPTSTR TheName; + LPTSTR ErrorText; + ULONG RetType; + + // Figure out which name to use + if (Groups->IsNewName) + TheName = Groups->Name; + else + TheName = Groups->NewName; + + // If using mapping file then map the name appropriatly + if (ConvOpt->UseMappingFile) { + if (GroupCacheMatch(TheName)) + Groups->err = NWC_ERR_DUPLICATE; + } else { + // check if the user name is in the destination list (duplicate) + if (GroupCacheMatch(TheName)) { + // There was - so figure out based on conversion options what + // to do with it... + switch (ConvOpt->GroupNameOption) { + case 0: // Log Errors + Groups->err = NWC_ERR_DUPLICATE; + break; + + case 1: // ignore + Groups->err = NWC_ERR_IGNORE; + break; + + case 2: // Pre-Pend constant + lstrcpy(NewName, ConvOpt->GroupConstant); + lstrcat(NewName, Groups->Name); + lstrcpy(Groups->NewName, NewName); + Groups->IsNewName = TRUE; + break; + } // switch + } + } + + do { + RetType = IDIGNORE; + GroupNewName_Check(Groups); + + if (Groups->err && (Groups->err != NWC_ERR_IGNORE) && PopupOnError()) { + switch(Groups->err) { + case NWC_ERR_NAMELONG: + ErrorText = Lids(IDS_L_182); + break; + + case NWC_ERR_DUPLICATE: + ErrorText = Lids(IDS_L_183); + break; + + case NWC_ERR_NAMEINVALID: + ErrorText = Lids(IDS_L_184); + break; + + } + + RetType = GroupNameErrorDlg_Do(Lids(IDS_L_185), ErrorText, Groups); + } + } while (RetType == IDRETRY); + + if (RetType == IDABORT) + TransferCancel = TRUE; + +} // GroupNames_Resolve + + +/*+-------------------------------------------------------------------------+ + | GroupsConvert() + | + +-------------------------------------------------------------------------+*/ +void GroupsConvert() { + USER_LIST *GUsers = NULL; + USER_BUFFER *GUserBuffer; + USER_BUFFER *pUser; + GROUP_BUFFER *pGroup; + GROUP_BUFFER *GroupBuffer = NULL; + DWORD GUserCount; + DWORD status = 0; + ULONG Count, i; + ULONG TotConv = 0; + LPTSTR NewName; + BOOL SecEquivTitle = FALSE; + BOOL SecEquivUser = FALSE; + TCHAR GroupTitle[TMP_STR_LEN_256]; + + // update status pane + Status_ConvTxt(Lids(IDS_D_20)); + Status_ItemLabel(Lids(IDS_D_21)); + ErrorCategorySet(Lids(IDS_L_186)); + + Status_CurTot((UINT) GroupCount); + LogWriteLog(0, Lids(IDS_L_187)); + LogWriteLog(1, Lids(IDS_L_188), GroupCount); + + if (Groups == NULL) + return; + + GroupBuffer = Groups->GroupBuffer; + + for (i = 0; i < GroupCount; i++) { + // Don't update totals yet, but update item ref incase this takes + // awhile + Status_CurNum((UINT) i + 1); + Status_Item(GroupBuffer[i].Name); + + GroupNames_Resolve(&GroupBuffer[i]); + + if (TransferCancel) + return; + } + + i = 0; + while (i < GroupCount) { + // update status pane for this group + Status_CurNum((UINT) i + 1); + Status_Item(GroupBuffer[i].Name); + lstrcpy(pLine, GroupBuffer[i].Name); + +#ifdef DEBUG +dprintf(TEXT("Working on Group: %s\r\n"), GroupBuffer[i].Name); +#endif + + if (GroupBuffer[i].IsNewName) + wsprintf(pLine, TEXT("%s -> %s"), GroupBuffer[i].Name, GroupBuffer[i].NewName); + else + wsprintf(pLine, TEXT("%s"), GroupBuffer[i].NewName); + + LogWriteLog(1, TEXT("%-50s"), pLine); + ErrorItemSet(TEXT("[%s]\r\n"), pLine); + + // If duplicate or other type error just do logging - don't try + // to save... + if (GroupBuffer[i].err) { + if (GroupBuffer[i].err == NWC_ERR_DUPLICATE) { + LogWriteLog(0, Lids(IDS_L_163)); + ErrorIt(Lids(IDS_L_189)); + } + + if (GroupBuffer[i].err == NWC_ERR_NAMELONG) { + LogWriteLog(0, Lids(IDS_L_162)); + ErrorIt(Lids(IDS_L_190)); + } + + if (GroupBuffer[i].err == NWC_ERR_NAMEINVALID) { + LogWriteLog(0, Lids(IDS_L_164)); + ErrorIt(Lids(IDS_L_191)); + } + + } else { + // Try to save it and get any errors... + if (!GroupSave(GroupBuffer[i].NewName, &status)) { + LogWriteLog(0, Lids(IDS_L_192)); + ErrorIt(Lids(IDS_L_193)); + } else { + // only increment total if actually converted... + TotGroups++; + TotConv++; + Status_TotGroups(TotGroups); + + LogWriteLog(0, Lids(IDS_L_180)); + } + } + + LogWriteLog(0, Lids(IDS_CRLF)); + + i++; + } + LogWriteLog(0, Lids(IDS_CRLF)); + + ErrorCategorySet(Lids(IDS_L_194)); + // +-------------------------------------------------------------+ + // | Go through and add users to the groups | + // +-------------------------------------------------------------+ + for (Count = 0; Count < GroupCount; Count++) { + GUserCount = 0; + + if (!(status = NWGroupUsersEnum(GroupBuffer[Count].Name, &GUsers)) && (GUsers != NULL)) { + GUserCount = GUsers->Count; + GUserBuffer = GUsers->UserBuffer; + + if (GUserCount > 0) { + wsprintf(GroupTitle, Lids(IDS_S_46), GroupBuffer[Count].NewName); + EscapeFormattingChars(GroupTitle, + sizeof(GroupTitle)/sizeof(GroupTitle[0])) ; + Status_ItemLabel(GroupTitle); + LogWriteLog(1, TEXT("[%s]\r\n"), GroupBuffer[Count].NewName); + } + + for (i = 0; i < GUserCount; i++) { + pUser = FindUserMatch(GUserBuffer[i].Name, Users, FALSE); + + if (pUser == NULL) + NewName = NWSpecialNamesMap(GUserBuffer[i].Name); + else + NewName = pUser->NewName; + + LogWriteLog(2, TEXT("%-20s"), NewName); + Status_Item(NewName); + +#ifdef DEBUG +dprintf(TEXT("Adding User [%s] to Group: %s\n"), NewName, GroupBuffer[Count].NewName ); +#endif + if (!TConversion) + if (NTGroupUserAdd(GroupBuffer[Count].NewName, NewName, FALSE)) { + LogWriteLog(0, Lids(IDS_L_196)); + ErrorIt(Lids(IDS_L_195), NewName, GroupBuffer[Count].NewName); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + FreeMemory((LPBYTE) GUsers); + } else { + LogWriteLog(1, Lids(IDS_L_197), GroupBuffer[Count].Name); + ErrorIt(Lids(IDS_L_197), GroupBuffer[Count].Name); + } + + } // loop adding users to groups + + ErrorCategorySet(Lids(IDS_L_198)); + // +-------------------------------------------------------------+ + // | Convert Security Equivalences to Group Names | + // +-------------------------------------------------------------+ + SecEquivTitle = FALSE; + for (Count = 0; Count < UserCount; Count++) { + GUserCount = 0; + SecEquivUser = FALSE; + + if (!(status = NWUserEquivalenceEnum(Users->UserBuffer[Count].Name, &GUsers)) && (GUsers != NULL)) { + GUserCount = GUsers->Count; + GUserBuffer = GUsers->UserBuffer; + + if (GUserCount > 0) { + for (i = 0; i < GUserCount; i++) { + pGroup = FindGroupMatch(GUserBuffer[i].Name, Groups, FALSE); + + if (pGroup != NULL) { + if ((pGroup->err != NWC_ERR_NAMELONG) && (pGroup->err != NWC_ERR_NAMEINVALID)) + if (!SecEquivTitle) { + SecEquivTitle = TRUE; + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_L_199)); + } + + if (!SecEquivUser) { + SecEquivUser = TRUE; + wsprintf(GroupTitle, Lids(IDS_S_47), Users->UserBuffer[Count].NewName); + EscapeFormattingChars(GroupTitle, + sizeof(GroupTitle)/sizeof(GroupTitle[0])) ; + Status_ItemLabel(GroupTitle); + LogWriteLog(1, TEXT("[%s]\r\n"), Users->UserBuffer[Count].NewName); + } + + LogWriteLog(2, TEXT("%-20s"), pGroup->NewName); + Status_Item(pGroup->NewName); +#ifdef DEBUG +dprintf(TEXT("User [%s] Security Equivalence: %s\n"), Users->UserBuffer[Count].NewName, pGroup->NewName ); +#endif + if (!TConversion) + if (NTGroupUserAdd(pGroup->NewName, Users->UserBuffer[Count].NewName, FALSE)) { + LogWriteLog(0, Lids(IDS_L_196)); + ErrorIt(Lids(IDS_L_195), Users->UserBuffer[Count].NewName, pGroup->NewName); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } else { + // There was not a group match - check if this is supervisor + // equivalence + if (!lstrcmpi(GUserBuffer[i].Name, Lids(IDS_S_28))) { + // Check if we should add them + if (ConvOpt->AdminAccounts) { + if (!SecEquivTitle) { + SecEquivTitle = TRUE; + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_L_199)); + } + + if (!SecEquivUser) { + SecEquivUser = TRUE; + LogWriteLog(1, TEXT("[%s]\r\n"), Users->UserBuffer[Count].NewName); + } + + LogWriteLog(2, TEXT("%-20s"), Lids(IDS_S_42)); + + if (!TConversion) + if (NTGroupUserAdd(Lids(IDS_S_42), Users->UserBuffer[Count].NewName, FALSE)) { + LogWriteLog(0, Lids(IDS_L_196)); + ErrorIt(Lids(IDS_L_195), Users->UserBuffer[Count].NewName, Lids(IDS_S_42)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } + } + } + } + + // Only put blank line if we logged this user + if (SecEquivUser) + LogWriteLog(0, Lids(IDS_CRLF)); + + } + + FreeMemory((LPBYTE) GUsers); + } + + } // Loop converting security equivalences + + // Synchronize the domain - we need to synch as Print Operators are a + // local group + NTDomainSynch(CurrentConvertList->FileServ); + + // Now set server to appropriate dest server (local group - so must + // be on dest server and not PDC or trusted domain)... + if ((status = NTServerSet(CurrentConvertList->FileServ->Name))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), CurrentConvertList->FileServ->Name); + ErrorIt(Lids(IDS_L_209), CurrentConvertList->FileServ->Name); + return; + } + + ErrorCategorySet(Lids(IDS_L_200)); + // +-------------------------------------------------------------+ + // | Do Print Operators | + // +-------------------------------------------------------------+ + SecEquivTitle = FALSE; + if (!(status = NWPrintOpsEnum(&GUsers)) && (GUsers != NULL)) { + GUserCount = GUsers->Count; + GUserBuffer = GUsers->UserBuffer; + + if (GUserCount > 0) { + for (i = 0; i < GUserCount; i++) { + + if (!SecEquivTitle) { + SecEquivTitle = TRUE; + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_L_201)); + } + + pUser = FindUserMatch(GUserBuffer[i].Name, Users, FALSE); + + if ((pUser == NULL) || ((pUser->err != NWC_ERR_NAMELONG) && (pUser->err != NWC_ERR_NAMEINVALID))) { + if (pUser == NULL) + NewName = NWSpecialNamesMap(GUserBuffer[i].Name); + else + NewName = pUser->NewName; + + LogWriteLog(2, TEXT("%-20s"), NewName); +#ifdef DEBUG +dprintf(TEXT("Adding User [%s] to Group: %s\n"), NewName, Lids(IDS_S_43) ); +#endif + if (!TConversion) + if (NTGroupUserAdd(Lids(IDS_S_43), NewName, TRUE)) { + LogWriteLog(0, Lids(IDS_L_196)); + ErrorIt(Lids(IDS_L_195), NewName, Lids(IDS_S_43)); + } + + LogWriteLog(0, Lids(IDS_CRLF)); + } + } + } + } + + LogWriteSummary(1, Lids(IDS_L_202), lToStr(TotConv)); + +} // GroupsConvert + + +/*+-------------------------------------------------------------------------+ + | SupervisorDefaultsConvert() + | + +-------------------------------------------------------------------------+*/ +void SupervisorDefaultsConvert(TRANSFER_LIST *tl) { + ULONG i; + void *Defaults; + BOOL ConvertDefaults = FALSE; + NT_DEFAULTS *NTDefaults = NULL; + NT_DEFAULTS CDefaults; + DEST_SERVER_BUFFER *oDServ = NULL; + TRANSFER_BUFFER *TList; + CONVERT_OPTIONS *ConvOpt; + + if (tl == NULL) + return; + + TList = tl->TList; + + memset(&CDefaults, 0, sizeof(CDefaults)); + LogWriteLog(0, Lids(IDS_LINE)); + LogWriteLog(0, Lids(IDS_BRACE), Lids(IDS_L_203)); + LogWriteLog(0, Lids(IDS_LINE)); + + // Loop through the server pairs for conversion - this is sorted in order of + // destination users servers. + for (i = 0; i < tl->Count; i++) { + CurrentConvertList = TList[i].ConvertList; + ConvOpt = (CONVERT_OPTIONS *) CurrentConvertList->ConvertOptions; + + if (CurrentConvertList->FileServ != oDServ) { + // if this is not the first time through the loop, then we need to save + // off the converted defaults + if (ConvertDefaults && (oDServ != NULL)) { + ConvertDefaults = FALSE; + LogWriteLog(0, Lids(IDS_L_204), oDServ->Name); + + if (NTDefaults != NULL) { + NTUserDefaultsLog(*NTDefaults); + + if (!TConversion) + NTUserDefaultsSet(*NTDefaults); + } + + } + + oDServ = CurrentConvertList->FileServ; + + // Point to dest server and get defaults + NTServerSet(CurrentConvertList->FileServ->Name); + NTUserDefaultsGet(&NTDefaults); + memset(&CDefaults, 0, sizeof(CDefaults)); + + if (NTDefaults != NULL) + memcpy(&CDefaults, NTDefaults, sizeof(CDefaults)); + + } + + // Supervisor defaults + if (ConvOpt->SupervisorDefaults) { + + // if not flagged for this dest server, then flag and write out original + // values + if (!ConvertDefaults) { + ConvertDefaults = TRUE; + + if (NTDefaults != NULL) { + LogWriteLog(0, Lids(IDS_L_205), CurrentConvertList->FileServ->Name); + NTUserDefaultsLog(*NTDefaults); + } + } + + NWServerSet(CurrentConvertList->SourceServ->Name); + NWUserDefaultsGet(&Defaults); + + if (Defaults != NULL) { + LogWriteLog(0, Lids(IDS_L_206), CurrentConvertList->SourceServ->Name); + NWUserDefaultsLog(Defaults); + NWUserDefaultsMap(Defaults, &CDefaults); + + // Now map in least restrictive values to the NT one + if (NTDefaults != NULL) { + if (CDefaults.min_passwd_len < NTDefaults->min_passwd_len) + NTDefaults->min_passwd_len = CDefaults.min_passwd_len; + + if (CDefaults.max_passwd_age < NTDefaults->max_passwd_age) + NTDefaults->max_passwd_age = CDefaults.max_passwd_age; + + if (CDefaults.force_logoff < NTDefaults->force_logoff) + NTDefaults->force_logoff = CDefaults.force_logoff; + + } + + FreeMemory(Defaults); + Defaults = NULL; + } + } + + } + + // Need to catch the last one through the loop + if (ConvertDefaults && (oDServ != NULL)) { + ConvertDefaults = FALSE; + LogWriteLog(0, Lids(IDS_L_204), oDServ->Name); + + if (NTDefaults != NULL) { + NTUserDefaultsLog(*NTDefaults); + + if (!TConversion) + NTUserDefaultsSet(*NTDefaults); + } + + } + + +} // SupervisorDefaultsConvert + + +/*+-------------------------------------------------------------------------+ + | TransferListCompare() + | + +-------------------------------------------------------------------------+*/ +int __cdecl TransferListCompare(const void *arg1, const void *arg2) { + TRANSFER_BUFFER *TBarg1, *TBarg2; + + TBarg1 = (TRANSFER_BUFFER *) arg1; + TBarg2 = (TRANSFER_BUFFER *) arg2; + + return lstrcmpi( TBarg1->ServerName, TBarg2->ServerName); + +} // TransferListCompare + + +/*+-------------------------------------------------------------------------+ + | TransferListCreate() + | + +-------------------------------------------------------------------------+*/ +TRANSFER_LIST *TransferListCreate() { + CONVERT_OPTIONS *ConvOpt; + static TRANSFER_LIST *tl; + TRANSFER_BUFFER *TList; + CONVERT_LIST *CList; + ULONG Count = 0; + + tl = NULL; + CList = ConvertListStart; + while (CList != NULL) { + Count++; + CList = CList->next; + } + + if (Count == 0) + return NULL; + + tl = AllocMemory(sizeof(TRANSFER_LIST) + (sizeof(TRANSFER_BUFFER) * Count)); + if (tl == NULL) + return NULL; + + tl->Count = Count; + TList = tl->TList; + + // init it all to NULL + memset(TList, 0, sizeof(TRANSFER_BUFFER) * Count); + + Count = 0; + CList = ConvertListStart; + while (CList != NULL) { + TList[Count].ConvertList = CList; + + // If going to a trusted domain then point to it's PDC for user transfers + ConvOpt = (CONVERT_OPTIONS *) CList->ConvertOptions; + if (ConvOpt->UseTrustedDomain && (ConvOpt->TrustedDomain != NULL) && (ConvOpt->TrustedDomain->PDCName != NULL)) { + TList[Count].UserServerType = USER_SERVER_TRUSTED; + TList[Count].ServerName = ConvOpt->TrustedDomain->PDCName; + } else + // If in a domain then point to the PDC for user transfers + if (CList->FileServ->InDomain && CList->FileServ->Domain) { + TList[Count].UserServerType = USER_SERVER_PDC; + TList[Count].ServerName = CList->FileServ->Domain->PDCName; + } else { + TList[Count].UserServerType = USER_SERVER; + TList[Count].ServerName = CList->FileServ->Name; + } + + Count++; + CList = CList->next; + } + + // Have setup the main transfer list - now need to sort it in order of the + // server names that users are being transfered to. + qsort((void *) TList, (size_t) tl->Count, sizeof(TRANSFER_BUFFER), TransferListCompare); + +#ifdef DEBUG +dprintf(TEXT("\nTransfer List:\n")); +for (Count = 0; Count < tl->Count; Count++) { + dprintf(TEXT(" Name: %s "), TList[Count].ServerName); + switch (TList[Count].UserServerType) { + case USER_SERVER: + dprintf(TEXT("(Normal)\n")); + break; + + case USER_SERVER_PDC: + dprintf(TEXT("(PDC)\n")); + break; + + case USER_SERVER_TRUSTED: + dprintf(TEXT("(TRUSTED)\n")); + break; + } +} + +dprintf(TEXT("\n")); +#endif + return tl; + +} // TransferListCreate + + +/*+-------------------------------------------------------------------------+ + | DoConversion() + | + | Main program that does the actuall conversion. Loops through the + | convert list and transfer the information. + | + +-------------------------------------------------------------------------+*/ +void DoConversion(HWND hDlg, BOOL TrialConversion) { + TRANSFER_LIST *tl = NULL; + TRANSFER_BUFFER *TList; + LPTSTR oDServ = NULL; + DWORD status = 0; + UINT i; + BOOL GotUserList; + TCHAR sztime[40]; + LPTSTR DomainName; + + time(&StartTime); + TransferCancel = FALSE; + TConversion = TrialConversion; + + // Check if going to non NTFS drives - if so, let user abort + NTFSCheck(hDlg); + if (TransferCancel) + return; + + CursorHourGlass(); + + PanelDlg_Do(hDlg, Lids(IDS_D_22)); + ConvertFilesInit(hDlg); + + if (Panel_Cancel()) { + PanelDlgKill(); + TransferCancel = TRUE; + CursorNormal(); + return; + } + + PanelDlgKill(); + + // Check if enough space on destination drives, if not allow user to abort + CursorNormal(); + SpaceCheck(hDlg); + if (TransferCancel) + return; + + CursorHourGlass(); + tl = TransferListCreate(); + TList = tl->TList; + + DoStatusDlg(hDlg); + + Status_TotConv((UINT) NumServerPairs); + + Users = NULL; + NTUsers = NULL; + Groups = NULL; + NTGroups = NULL; + UserCount = 0; + NTUserCount = 0; + GroupCount = 0; + NTGroupCount= 0; + + // Initialize global statistics + TotErrors = 0; + TotGroups = 0; + TotUsers = 0; + TotFiles = 0; + + // Update statistics window + Status_TotComplete(0); + Status_TotGroups(TotGroups); + Status_TotUsers(TotUsers); + Status_TotFiles(TotFiles); + Status_TotErrors(TotErrors); + + // Set up logs and do all the header stuff + LogInit(); + + if (TrialConversion) { + LogWriteLog(0, Lids(IDS_L_207)); + } else { + LogWriteLog(0, Lids(IDS_L_208)); + } + + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteErr(Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_CRLF)); + + // Log the list of servers to be converted + ErrorResetAll(); + ConvertListLog(); + + // Loop through source servers and conglomerate defaults into dest servers + // and log the results + SupervisorDefaultsConvert(tl); + + + // +---------------------------------------------------------------------+ + // | Done with init - loop through server pairs and do conversion | + // +---------------------------------------------------------------------+ + + // Get Local computer name + GetLocalName(&LocalName); + + // Loop through the server pairs for conversion + for (i = 0; ((i < tl->Count) && !TransferCancel); i++) { + CurrentConvertList = TList[i].ConvertList; + + // Get source and destination server - update logs and status window + Status_CurConv(i + 1); + + SourceServer = CurrentConvertList->SourceServ->Name; + DestServer = CurrentConvertList->FileServ->Name; + + Status_SrcServ(SourceServer); + Status_DestServ(DestServer); + + // Log this server pair - section heading + ConvertPairLog(); + + // SetConvert options and log them out. + ConvOpt = (CONVERT_OPTIONS *) CurrentConvertList->ConvertOptions; + FileOptions = (FILE_OPTIONS *) CurrentConvertList->FileOptions; + ConvertOptionsLog(); + OptionsFileLog(); + + // If our destination server has changed then update the caches + if (TList[i].ServerName != oDServ) { + oDServ = TList[i].ServerName; + GotUserList = TRUE; + + ListCacheFree(&UserCacheHead); + ListCacheFree(&GroupCacheHead); + if ((status = NTServerSet(DestServer))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), DestServer); + ErrorIt(Lids(IDS_L_209), DestServer); + goto ConvDo_Loop; + } + + // Put VShares here so it doesn't get lost in user info + if (FileOptions->TransferFileInfo) + VSharesCreate(CurrentConvertList->FileServ, TConversion); + + // Get users on NT server and put in cache + if (status = NTUsersEnum(&NTUsers)) { + // Failed - make sure we don't try to convert users and log err + NTUsers = NULL; + NTUserCount = 0; + LogWriteLog(0, Lids(IDS_L_210), DestServer); + ErrorIt(Lids(IDS_L_210), DestServer); + GotUserList = FALSE; + } else + NTUserCount = NTUsers->Count; + + if (!ListCachePut(&UserCacheHead, (void *) NTUsers, NTUserCount)) { + // Failed - but clean up NT List first + GotUserList = FALSE; + FreeMemory(NTUsers); + } else { + // Now get Groups (if users succeded) and put in group cache + if (status = NTGroupsEnum(&NTGroups)) { + // Failed - make sure we don't try to convert users and log err + NTGroupCount = 0; + NTGroups = NULL; + LogWriteLog(0, Lids(IDS_L_211), DestServer); + ErrorIt(Lids(IDS_L_211), DestServer); + FreeMemory(NTUsers); + GotUserList = FALSE; + } else + NTGroupCount = NTGroups->Count; + + if (!ListCachePut(&GroupCacheHead, (void *) NTGroups, NTGroupCount)) { + // Failed - but clean up NT List first + GotUserList = FALSE; + FreeMemory(NTUsers); + FreeMemory(NTGroups); + } + } + + } + + wsprintf(UserServerName, TEXT("\\\\%s"), TList[i].ServerName); + if ((status = NTServerSet(TList[i].ServerName))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), TList[i].ServerName); + ErrorIt(Lids(IDS_L_209), TList[i].ServerName); + goto ConvDo_Loop; + } + + if (ConvOpt->NetWareInfo) { + NTSAMClose(); + + if (ConvOpt->UseTrustedDomain && (ConvOpt->TrustedDomain != NULL)) + DomainName = ConvOpt->TrustedDomain->Name; + else + if ((CurrentConvertList->FileServ->InDomain) && (CurrentConvertList->FileServ->Domain != NULL)) + DomainName = CurrentConvertList->FileServ->Domain->Name; + else + DomainName = TEXT(""); + + if ((status = NTSAMConnect(TList[i].ServerName, DomainName))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), TList[i].ServerName); + ErrorIt(Lids(IDS_L_209), TList[i].ServerName); + goto ConvDo_Loop; + } + } + + if ((status = NWServerSet(SourceServer))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), SourceServer); + ErrorIt(Lids(IDS_L_209), SourceServer); + goto ConvDo_Loop; + } + + // + // If we are using mapping file then don't enum users and groups off + // the server. Get them from the mapping file instead. + // + hMap = NULL; + if (ConvOpt->UseMappingFile) { + // + // This is mapping file stuff + // + hMap = map_Open(ConvOpt->MappingFile); + if (hMap == NULL) { + ErrorIt(Lids(IDS_L_217), ConvOpt->MappingFile); + goto ConvDo_Loop; + } + + if ((status = map_GroupsEnum(hMap, &Groups))) { + // Failed - make sure we don't try to convert users and log err + Groups = NULL; + GroupCount = 0; + LogWriteLog(0, Lids(IDS_L_219), ConvOpt->MappingFile); + ErrorIt(Lids(IDS_L_219), ConvOpt->MappingFile); + GotUserList = FALSE; + } else + GroupCount = Groups->Count; + + if ((status = map_UsersEnum(hMap, &Users))) { + // Failed - make sure we don't try to convert users and log err + Users = NULL; + UserCount = 0; + LogWriteLog(0, Lids(IDS_L_218), ConvOpt->MappingFile); + ErrorIt(Lids(IDS_L_218), ConvOpt->MappingFile); + GotUserList = FALSE; + } else + UserCount = Users->Count; + + } else { + // + // Enuming users and groups from NetWare Server instead of map file + // + if ((status = NWGroupsEnum(&Groups, TRUE))) { + // Failed - make sure we don't try to convert users and log err + Groups = NULL; + GroupCount = 0; + LogWriteLog(0, Lids(IDS_L_211), SourceServer); + ErrorIt(Lids(IDS_L_211), SourceServer); + GotUserList = FALSE; + } else + GroupCount = Groups->Count; + + if ((status = NWUsersEnum(&Users, TRUE))) { + // Failed - make sure we don't try to convert users and log err + Users = NULL; + UserCount = 0; + LogWriteLog(0, Lids(IDS_L_210), SourceServer); + ErrorIt(Lids(IDS_L_210), SourceServer); + GotUserList = FALSE; + } else + UserCount = Users->Count; + } + + if (GotUserList) { + // User and Groups + if (ConvOpt->TransferUserInfo) { + UsersConvert(); + + if (!TransferCancel) + GroupsConvert(); + } + } + + // Note GroupsConvert switches servers for Print Operators to the + // destination server (and not the PDC). + + // Files + if (!(TransferCancel) && FileOptions->TransferFileInfo) { + ErrorCategorySet(Lids(IDS_L_212)); + + // Now set server to appropriate file dest server + if ((status = NTServerSet(CurrentConvertList->FileServ->Name))) { + // Failed to set server so log it and loop to next server + LogWriteLog(0, Lids(IDS_L_209), CurrentConvertList->FileServ->Name); + ErrorIt(Lids(IDS_L_209), CurrentConvertList->FileServ->Name); + goto ConvDo_Loop; + } + + Status_BytesTxt(Lids(IDS_L_213)); + Status_Bytes(TEXT("0")); + Status_TotBytes(TEXT("0")); + Status_BytesSep(Lids(IDS_L_214)); + ConvertFiles(hDlg, TConversion, Users, Groups); + Status_BytesTxt(TEXT("")); + Status_Bytes(TEXT("")); + Status_TotBytes(TEXT("")); + Status_BytesSep(TEXT("")); + } + + NWServerFree(); + +ConvDo_Loop: + Status_TotComplete(i); + + if (Users) { + FreeMemory(Users); + UserCount = 0; + } + + if (Groups) { + FreeMemory(Groups); + GroupCount = 0; + } + + if (hMap != NULL) + map_Close(hMap); + + } // for loop through transfer list + + // Free up our caches + ListCacheFree(&UserCacheHead); + ListCacheFree(&GroupCacheHead); + + // Log out the finish time + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteSummary(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_CRLF)); + LogWriteLog(0, Lids(IDS_CRLF)); + GetTime(sztime); + + if (TransferCancel) { + LogWriteLog(0, Lids(IDS_L_215), sztime); + LogWriteSummary(0, Lids(IDS_L_215), sztime); + } else { + LogWriteLog(0, Lids(IDS_L_216), sztime); + LogWriteSummary(0, Lids(IDS_L_216), sztime); + } + + if (tl != NULL) + FreeMemory(tl); + + NTSAMClose(); + StatusDlgKill(); + CursorNormal(); + + TotConversions = i; + ConversionEndDlg_Do(hDlg); + +} // DoConversion + + +/*+-------------------------------------------------------------------------+ + | ConversionSuccessful() + | + +-------------------------------------------------------------------------+*/ +BOOL ConversionSuccessful() { + if (TotErrors || TransferCancel) + return FALSE; + else + return TRUE; + +} // ConversionSuccesful diff --git a/private/nw/convert/nwconv/transfer.h b/private/nw/convert/nwconv/transfer.h new file mode 100644 index 000000000..0a766548a --- /dev/null +++ b/private/nw/convert/nwconv/transfer.h @@ -0,0 +1,19 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _TRANSFER_ +#define _TRANSFER_ + +#ifdef __cplusplus +extern "C"{ +#endif + +void DoConversion(HWND hDlg, BOOL TrialConversion); +BOOL ConversionSuccessful(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/userdlg.c b/private/nw/convert/nwconv/userdlg.c new file mode 100644 index 000000000..5ceb86465 --- /dev/null +++ b/private/nw/convert/nwconv/userdlg.c @@ -0,0 +1,1266 @@ +/* + +-------------------------------------------------------------------------+ + | User Options Dialog | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [UserDlg.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Feb 15, 1993] | + | Last Update : [Jun 16, 1994] | + | | + | Version: 1.00 | + | | + | Description: | + | | + | History: | + | arth Jun 16, 1994 1.00 Original Version. | + | | + +-------------------------------------------------------------------------+ +*/ + + +#include "globals.h" + +#include + +#include "nwconv.h" +#include "convapi.h" +#include "userdlg.h" +#include "transfer.h" +#include "ntnetapi.h" +#include "map.h" + +#define togmap 1 + +// Utility Macros for Advanced >> button +#define SetStyleOn(hWnd, Style) SetWindowLong(hWnd, GWL_STYLE, Style | GetWindowLong(hWnd, GWL_STYLE)); + +#define SetStyleOff(hWnd, Style) SetWindowLong(hWnd, GWL_STYLE, ~Style & GetWindowLong(hWnd, GWL_STYLE)); + + +static CONVERT_OPTIONS cvoDefault; +static CONVERT_OPTIONS *CurrentConvertOptions; +static LPTSTR SourceServ; +static LPTSTR DestServ; +static SOURCE_SERVER_BUFFER *SServ; +static DEST_SERVER_BUFFER *DServ; +static BOOL FPNWChk; +static short TabSelection; + +/*+-------------------------------------------------------------------------+ + | UserOptionsDefaultsSet() + | + +-------------------------------------------------------------------------+*/ +void UserOptionsDefaultsSet(void *cvto) { + memcpy((void *) &cvoDefault, cvto, sizeof(CONVERT_OPTIONS)); + +} // UserOptionsDefaultsSet + + +/*+-------------------------------------------------------------------------+ + | UserOptionsDefaultsReset() + | + +-------------------------------------------------------------------------+*/ +void UserOptionsDefaultsReset() { + memset(&cvoDefault, 0, sizeof(CONVERT_OPTIONS)); + + cvoDefault.TransferUserInfo = TRUE; + cvoDefault.ForcePasswordChange = TRUE; + cvoDefault.SupervisorDefaults = TRUE; + cvoDefault.AdminAccounts = FALSE; + cvoDefault.NetWareInfo = FALSE; + cvoDefault.GroupNameOption = 1; + +} // UserOptionsDefaultsReset + + +/*+-------------------------------------------------------------------------+ + | UserOptionsInit() + | + +-------------------------------------------------------------------------+*/ +void UserOptionsInit(void **lpcvto) { + CONVERT_OPTIONS *cvto; + + cvto = (CONVERT_OPTIONS *) *lpcvto; + + // if we need to allocate space, do so + if (cvto == NULL) + cvto = AllocMemory(sizeof(CONVERT_OPTIONS)); + + // make sure it was allocated + if (cvto == NULL) + return; + + memcpy(cvto, (void *) &cvoDefault, sizeof(CONVERT_OPTIONS)); + *lpcvto = (void *) cvto; + +} // UserOptionsInit + + +/*+-------------------------------------------------------------------------+ + | UserOptionsLoad() + | + +-------------------------------------------------------------------------+*/ +void UserOptionsLoad(HANDLE hFile, void **lpcvto) { + CONVERT_OPTIONS *cvto; + DWORD wrote; + + cvto = (CONVERT_OPTIONS *) *lpcvto; + + // if we need to allocate space, do so + if (cvto == NULL) + cvto = AllocMemory(sizeof(CONVERT_OPTIONS)); + + // make sure it was allocated + if (cvto == NULL) + return; + + ReadFile(hFile, cvto, sizeof(CONVERT_OPTIONS), &wrote, NULL); + *lpcvto = (void *) cvto; + +} // UserOptionsLoad + + +/*+-------------------------------------------------------------------------+ + | UserOptionsSave() + | + +-------------------------------------------------------------------------+*/ +void UserOptionsSave(HANDLE hFile, void *pcvto) { + CONVERT_OPTIONS *cvto; + DWORD wrote; + DOMAIN_BUFFER *Trusted; + + cvto = (CONVERT_OPTIONS *) pcvto; + + // if trusted domain then index the domain list and save off the old + // domain pointer so that we save the index instead. + if (cvto->UseTrustedDomain && (cvto->TrustedDomain != NULL)) { + DomainListIndex(); + Trusted = cvto->TrustedDomain; + cvto->TrustedDomain = (DOMAIN_BUFFER *) cvto->TrustedDomain->Index; + } else + cvto->UseTrustedDomain = FALSE; + + WriteFile(hFile, pcvto, sizeof(CONVERT_OPTIONS), &wrote, NULL); + + // if we replaced the domain pointer, then restore it + if (cvto->UseTrustedDomain) + cvto->TrustedDomain = Trusted; + +} // UserOptionsSave + + +/*+-------------------------------------------------------------------------+ + | Passwords_Toggle() + | + +-------------------------------------------------------------------------+*/ +void Passwords_Toggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + BOOL MainToggle = Toggle; + + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 0) + MainToggle = FALSE; + + hCtrl = GetDlgItem(hDlg, IDC_CHKPWFORCE); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + +#ifdef togmap + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + MainToggle = FALSE; +#endif + + hCtrl = GetDlgItem(hDlg, IDC_RADIO1); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO2); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO3); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + +} // Passwords_Toggle + + +/*+-------------------------------------------------------------------------+ + | DuplicateUsers_Toggle() + | + +-------------------------------------------------------------------------+*/ +void DuplicateUsers_Toggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + BOOL MainToggle = Toggle; + + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 0) + MainToggle = FALSE; + +#ifdef togmap + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + MainToggle = FALSE; +#endif + + hCtrl = GetDlgItem(hDlg, IDC_STATDUP); + ShowWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO4); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO5); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO6); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO7); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_USERCONST); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + +} // DuplicateUsers_Toggle + + +/*+-------------------------------------------------------------------------+ + | DuplicateGroups_Toggle() + | + +-------------------------------------------------------------------------+*/ +void DuplicateGroups_Toggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + BOOL MainToggle = Toggle; + + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 0) + MainToggle = FALSE; + +#ifdef togmap + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + MainToggle = FALSE; +#endif + + hCtrl = GetDlgItem(hDlg, IDC_STATDUP); + ShowWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO8); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO9); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_RADIO10); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + + hCtrl = GetDlgItem(hDlg, IDC_GROUPCONST); + ShowWindow(hCtrl, Toggle); + EnableWindow(hCtrl, MainToggle); + +} // DuplicateGroups_Toggle + + +/*+-------------------------------------------------------------------------+ + | Defaults_Toggle() + | + +-------------------------------------------------------------------------+*/ +void Defaults_Toggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + BOOL MainToggle = Toggle; + + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 0) + MainToggle = FALSE; + + hCtrl = GetDlgItem(hDlg, IDC_CHKSUPER); + EnableWindow(hCtrl, MainToggle); + ShowWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_CHKADMIN); + EnableWindow(hCtrl, MainToggle); + ShowWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_CHKFPNW); + if (FPNWChk) + EnableWindow(hCtrl, MainToggle); + else + EnableWindow(hCtrl, FALSE); + + ShowWindow(hCtrl, Toggle); +} // Defaults_Toggle + + +/*+-------------------------------------------------------------------------+ + | Mapping_Toggle() + | + +-------------------------------------------------------------------------+*/ +void Mapping_Toggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + + // These two are the reverse of the others... + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + EnableWindow(hCtrl, !Toggle); + hCtrl = GetDlgItem(hDlg, IDC_BTNMAPPINGFILE); + EnableWindow(hCtrl, !Toggle); + hCtrl = GetDlgItem(hDlg, IDC_BTNMAPPINGEDIT); + EnableWindow(hCtrl, !Toggle); + +#ifdef togmap + hCtrl = GetDlgItem(hDlg, IDC_RADIO1); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO2); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO3); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO4); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO5); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO6); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO7); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO8); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO9); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_RADIO10); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_CHKPWFORCE); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_USERCONST); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_GROUPCONST); + EnableWindow(hCtrl, Toggle); +#endif + +} // Mapping_Toggle + + +/*+-------------------------------------------------------------------------+ + | UserDialogToggle() + | + +-------------------------------------------------------------------------+*/ +void UserDialogToggle(HWND hDlg, BOOL Toggle) { + HWND hCtrl; + + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + EnableWindow(hCtrl, Toggle); + + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + Mapping_Toggle(hDlg, FALSE); + else + Mapping_Toggle(hDlg, Toggle); + + if (!Toggle) { + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_BTNMAPPINGFILE); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_BTNMAPPINGEDIT); + EnableWindow(hCtrl, Toggle); + } + + hCtrl = GetDlgItem(hDlg, IDC_CHKSUPER); + EnableWindow(hCtrl, Toggle); + hCtrl = GetDlgItem(hDlg, IDC_CHKADMIN); + EnableWindow(hCtrl, Toggle); + + hCtrl = GetDlgItem(hDlg, IDC_CHKFPNW); + if (FPNWChk) + EnableWindow(hCtrl, Toggle); + else + EnableWindow(hCtrl, FALSE); + + // Check the Advanced Trusted domain check and toggle controls appropriatly + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, Toggle); + + } else { + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, FALSE); + + } + + // Now toggle the checkbox itself + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + EnableWindow(hCtrl, Toggle); + +} // UserDialogToggle + + +/*+-------------------------------------------------------------------------+ + | UserDialogSave() + | + +-------------------------------------------------------------------------+*/ +void UserDialogSave(HWND hDlg) { + HWND hCtrl; + DWORD dwIndex; + TCHAR TrustedDomain[MAX_PATH + 1]; + + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->TransferUserInfo = TRUE; + else + CurrentConvertOptions->TransferUserInfo = FALSE; + + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->UseMappingFile = TRUE; + else + CurrentConvertOptions->UseMappingFile = FALSE; + + // Mapping file is handled in Verify + + // Password stuff-------------------------------------------------------- + hCtrl = GetDlgItem(hDlg, IDC_RADIO1); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->PasswordOption = 0; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO2); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->PasswordOption = 1; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO3); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->PasswordOption = 2; + + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + * (WORD *)CurrentConvertOptions->PasswordConstant = sizeof(CurrentConvertOptions->PasswordConstant); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) CurrentConvertOptions->PasswordConstant); + + hCtrl = GetDlgItem(hDlg, IDC_CHKPWFORCE); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->ForcePasswordChange = TRUE; + else + CurrentConvertOptions->ForcePasswordChange = FALSE; + + // Username stuff-------------------------------------------------------- + hCtrl = GetDlgItem(hDlg, IDC_RADIO4); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->UserNameOption = 0; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO5); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->UserNameOption = 1; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO6); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->UserNameOption = 2; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO7); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->UserNameOption = 3; + + hCtrl = GetDlgItem(hDlg, IDC_USERCONST); + * (WORD *)CurrentConvertOptions->UserConstant = sizeof(CurrentConvertOptions->UserConstant); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) CurrentConvertOptions->UserConstant); + + // Group-name stuff-------------------------------------------------------- + hCtrl = GetDlgItem(hDlg, IDC_RADIO8); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->GroupNameOption = 0; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO9); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->GroupNameOption = 1; + + hCtrl = GetDlgItem(hDlg, IDC_RADIO10); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->GroupNameOption = 2; + + hCtrl = GetDlgItem(hDlg, IDC_GROUPCONST); + * (WORD *)CurrentConvertOptions->GroupConstant = sizeof(CurrentConvertOptions->GroupConstant); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) CurrentConvertOptions->GroupConstant); + + + // Defaults page stuff------------------------------------------------------ + hCtrl = GetDlgItem(hDlg, IDC_CHKSUPER); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->SupervisorDefaults = TRUE; + else + CurrentConvertOptions->SupervisorDefaults = FALSE; + + hCtrl = GetDlgItem(hDlg, IDC_CHKADMIN); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->AdminAccounts = TRUE; + else + CurrentConvertOptions->AdminAccounts = FALSE; + + if (FPNWChk) { + hCtrl = GetDlgItem(hDlg, IDC_CHKFPNW); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + CurrentConvertOptions->NetWareInfo = TRUE; + else + CurrentConvertOptions->NetWareInfo = FALSE; + } else + CurrentConvertOptions->NetWareInfo = FALSE; + + + // Advanced >> button stuff------------------------------------------------- + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + CurrentConvertOptions->UseTrustedDomain = TRUE; + + // if there is already a trusted domain selected - clear it out + if (CurrentConvertOptions->TrustedDomain != NULL) { + DomainListDelete(CurrentConvertOptions->TrustedDomain); + CurrentConvertOptions->TrustedDomain = NULL; + } + + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0); + + if (dwIndex != CB_ERR) { + // Get the domain name and then try to add it to our lists + SendMessage(hCtrl, CB_GETLBTEXT, (WPARAM) dwIndex, (LPARAM) TrustedDomain); + CurrentConvertOptions->TrustedDomain = NTTrustedDomainSet(hDlg, DestServ, TrustedDomain); + } + + } else + CurrentConvertOptions->UseTrustedDomain = FALSE; + + // Set default values to new selections + UserOptionsDefaultsSet(CurrentConvertOptions); + +} // UserDialogSave + + +/*+-------------------------------------------------------------------------+ + | UserDialogVerify() + | + +-------------------------------------------------------------------------+*/ +BOOL UserDialogVerify(HWND hDlg) { + HWND hCtrl; + static TCHAR MappingFile[MAX_PATH + 1]; + static char FileNameA[MAX_PATH + 1]; + static char CmdLine[MAX_PATH + 1 + 12]; // Editor + file + TCHAR drive[MAX_DRIVE + 1]; + TCHAR dir[MAX_PATH + 1]; + TCHAR fname[MAX_PATH + 1]; + TCHAR ext[_MAX_EXT + 1]; + HANDLE hFile; + + // Check trusted domain... + + // Check mapping file + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + * (WORD *)MappingFile = sizeof(MappingFile); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) MappingFile); + lsplitpath(MappingFile, drive, dir, fname, ext); + + // Make sure a file name is specified + if (lstrlen(fname) == 0) { + MessageBox(hDlg, Lids(IDS_NOREADMAP), Lids(IDS_TXTWARNING), MB_OK | MB_ICONEXCLAMATION); + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SetFocus(hCtrl); + return FALSE; + } + + if ((drive[0] == TEXT('\0')) && (dir[0] == TEXT('\0'))) + lstrcpy(dir, ProgPath); + + if (ext[0] == TEXT('\0')) + lstrcpy(ext, Lids(IDS_S_36)); + + lmakepath(MappingFile, drive, dir, fname, ext); + + lstrcpy(CurrentConvertOptions->MappingFile, MappingFile); + + WideCharToMultiByte(CP_ACP, 0, MappingFile, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + hFile = CreateFileA( FileNameA, GENERIC_READ, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(hDlg, Lids(IDS_NOREADMAP), Lids(IDS_TXTWARNING), MB_OK | MB_ICONEXCLAMATION); + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SetFocus(hCtrl); + return FALSE; + } else + CloseHandle(hFile); + + } + } // mapping file + + return TRUE; + +} // UserDialogVerify + + +/*+-------------------------------------------------------------------------+ + | UserDialogSetup() + | + +-------------------------------------------------------------------------+*/ +void UserDialogSetup(HWND hDlg) { + HWND hCtrl; + + // Main TransferUserCheckbox + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (CurrentConvertOptions->TransferUserInfo) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + // Mapping file checkbox + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (CurrentConvertOptions->UseMappingFile) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PATH, 0); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) CurrentConvertOptions->MappingFile); + + // Force Password checkbox + hCtrl = GetDlgItem(hDlg, IDC_CHKPWFORCE); + if (CurrentConvertOptions->ForcePasswordChange) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + // Set the text and limit the lengths of the edit fields... + hCtrl = GetDlgItem(hDlg, IDC_PWCONST); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_PW_LEN, 0); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) CurrentConvertOptions->PasswordConstant); + + hCtrl = GetDlgItem(hDlg, IDC_USERCONST); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_UCONST_LEN, 0); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) CurrentConvertOptions->UserConstant); + + hCtrl = GetDlgItem(hDlg, IDC_GROUPCONST); + PostMessage(hCtrl, EM_LIMITTEXT, (WPARAM) MAX_UCONST_LEN, 0); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) CurrentConvertOptions->GroupConstant); + + // Now init the radio buttons correctly + CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1 + CurrentConvertOptions->PasswordOption); + CheckRadioButton(hDlg, IDC_RADIO4, IDC_RADIO7, IDC_RADIO4 + CurrentConvertOptions->UserNameOption); + CheckRadioButton(hDlg, IDC_RADIO8, IDC_RADIO10, IDC_RADIO8 + CurrentConvertOptions->GroupNameOption); + + // Do the controls in the defaults section + hCtrl = GetDlgItem(hDlg, IDC_CHKSUPER); + if (CurrentConvertOptions->SupervisorDefaults) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + hCtrl = GetDlgItem(hDlg, IDC_CHKADMIN); + if (CurrentConvertOptions->AdminAccounts) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + if (FPNWChk) { + hCtrl = GetDlgItem(hDlg, IDC_CHKFPNW); + if (CurrentConvertOptions->NetWareInfo) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + } else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + + // Now for the Advanced >> area.. + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + if (CurrentConvertOptions->UseTrustedDomain) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + else + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + +} // UserDialogSetup + + + +/*+-------------------------------------------------------------------------+ + | ShowArea() + | + +-------------------------------------------------------------------------+*/ +void ShowArea(BOOL fShowDefAreaOnly, HWND hDlg, HWND hWndDefArea) { + RECT rcDlg, rcDefArea; + TCHAR szDlgDims[25]; + char szaDlgDims[25]; + HWND hWndChild; + RECT rc; + + // Save original width and height of dialog box + GetWindowRect(hDlg, &rcDlg); + + // Retrieve coordinates for default area window. + GetWindowRect(hWndDefArea, &rcDefArea); + + hWndChild = GetFirstChild(hDlg); + + for (; hWndChild != NULL; hWndChild = GetNextSibling(hWndChild)) { + // Calculate rectangle occupied by child window in sreen coordinates + GetWindowRect(hWndChild, &rc); + + // Enable/Disable child if its: + // right edge is >= the right edge of hWndDefArea. + // bottom edge is >= the bottom edge of hWndDefArea. + if ((rc.right >= rcDefArea.right) || (rc.bottom >= rcDefArea.bottom)) + EnableWindow(hWndChild, !fShowDefAreaOnly); + } + + if (fShowDefAreaOnly) { + wsprintf(szDlgDims, TEXT("%05u %05u"), rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top); + + SetStyleOff(hWndDefArea, SS_BLACKRECT); + SetStyleOn(hWndDefArea, SS_LEFT); + SetWindowText(hWndDefArea, szDlgDims); + + // Resize dialog box to fit only default area. + SetWindowPos(hDlg, NULL, 0, 0, rcDefArea.right - rcDlg.left, + rcDefArea.bottom - rcDlg.top, SWP_NOZORDER | SWP_NOMOVE); + + // Make sure that the Default area box is hidden. + ShowWindow(hWndDefArea, SW_HIDE); + } else { + GetWindowText(hWndDefArea, szDlgDims, sizeof(szDlgDims)); + + WideCharToMultiByte( CP_ACP, 0, szDlgDims, -1, szaDlgDims, sizeof(szDlgDims), NULL, NULL ); + + // Restore dialog box to its original size. + SetWindowPos(hDlg, NULL, 0, 0, atoi(szaDlgDims), atoi(szaDlgDims + 6), + SWP_NOZORDER | SWP_NOMOVE); + } + + +} // ShowArea + + +/*+-------------------------------------------------------------------------+ + | UserFileGet() + | + +-------------------------------------------------------------------------+*/ +DWORD UserFileGet(HWND hwnd, LPTSTR FilePath) { + OPENFILENAME ofn; + TCHAR szDirName[MAX_PATH + 1]; + TCHAR szFile[MAX_PATH + 1], szFileTitle[MAX_PATH + 1]; + UINT i, cbString; + TCHAR chReplace; + TCHAR szFilter[256]; + BOOL Found = FALSE; + LPTSTR szExt; + + szExt = Lids(IDS_S_37); + + lstrcpy(szDirName, ProgPath); + lstrcpy(szFile, TEXT("")); + + if ((cbString = LoadString(hInst, IDS_USERFILTERSTRING, szFilter, sizeof(szFilter))) == 0) { + // Error occured + return 1L; + } + + chReplace = szFilter[cbString - 1]; // Retrieve wild character + + for (i = 0; szFilter[i] != TEXT('\0'); i++) { + if (szFilter[i] == chReplace) + szFilter[i] = TEXT('\0'); + } + + // Set all structure members to zero + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrDefExt = szExt; + ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; + + if (GetOpenFileName(&ofn)) { + // Don't really need to open it yet - just copy the data + + // If no path then append . + i = 0; + while (!Found && (ofn.lpstrFile[i] != TEXT('\0'))) { + if ((ofn.lpstrFile[i] == TEXT(':')) || (ofn.lpstrFile[i] == TEXT('\\'))) + Found = TRUE; + i++; + } + + lstrcpy(FilePath, TEXT("")); + + if (!Found) + lstrcpy(FilePath, TEXT(".\\")); + + lstrcat(FilePath, ofn.lpstrFile); + return 0L; + } else { + // Couldn't open the dang file + return 1L; + } + +} // UserFileGet + + +/*+-------------------------------------------------------------------------+ + | DlgUsers_TrustedSetup() + | + +-------------------------------------------------------------------------+*/ +void DlgUsers_TrustedSetup(HWND hDlg) { + HWND hCtrl; + ULONG i; + static TRUSTED_DOMAIN_LIST *TList = NULL; + + NTTrustedDomainsEnum(DestServ, &TList); + + if (TList != NULL) { + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + + for (i = 0; i < TList->Count; i++) + SendMessage(hCtrl, CB_ADDSTRING, (WPARAM) 0, (LPARAM) TList->Name[i]); + + } + + EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED), FALSE); + ShowArea(FALSE, hDlg, GetDlgItem(hDlg, IDC_DEFAULTBOX)); + + // Toggle the advanced controls based on the main user toggle + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + EnableWindow(hCtrl, TRUE); + + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, TRUE); + SetFocus(GetDlgItem(hDlg, IDC_CHKTRUSTED)); + } else { + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + EnableWindow(hCtrl, FALSE); + + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, FALSE); + SetFocus(GetDlgItem(hDlg, IDHELP)); + } + + + if ((TList == NULL) || (TList->Count = 0)) { + EnableWindow(GetDlgItem(hDlg, IDC_CHKTRUSTED), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_TRUSTED), FALSE); + SetFocus(GetDlgItem(hDlg, IDHELP)); + } else { + // Select the trusted domain (or first one if none currently selected) + if (CurrentConvertOptions->TrustedDomain != NULL) + SendMessage(GetDlgItem(hDlg, IDC_TRUSTED), CB_SELECTSTRING, (WPARAM) -1, (LPARAM) CurrentConvertOptions->TrustedDomain->Name); + else + SendMessage(GetDlgItem(hDlg, IDC_TRUSTED), CB_SETCURSEL, 0, 0); + + // if the checkbox is set then enable the edit field + if (!CurrentConvertOptions->UseTrustedDomain) + EnableWindow(GetDlgItem(hDlg, IDC_TRUSTED), FALSE); + + } + + // Free up the list as we don't need it anymore (it is in the combo-box) + if (TList) { + FreeMemory(TList); + TList = NULL; + } + +} // DlgUsers_TrustedSetup + + +/*+-------------------------------------------------------------------------+ + | MappingFileEdit() + | + +-------------------------------------------------------------------------+*/ +BOOL MappingFileEdit(HWND hDlg) { + HWND hCtrl; + static TCHAR MappingFile[MAX_PATH + 1]; + static char FileNameA[MAX_PATH + 1]; + static char CmdLine[MAX_PATH + 1 + 12]; // Editor + file + TCHAR drive[MAX_DRIVE + 1]; + TCHAR dir[MAX_PATH + 1]; + TCHAR fname[MAX_PATH + 1]; + TCHAR ext[_MAX_EXT + 1]; + HANDLE hFile; + UINT uReturn; + BOOL ret = TRUE; + BOOL Browse = FALSE; + + do { + // First check filename + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + * (WORD *)MappingFile = sizeof(MappingFile); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) MappingFile); + lsplitpath(MappingFile, drive, dir, fname, ext); + + // Make sure a file name is specified + if (Browse || (lstrlen(fname) == 0)) { + // No name was specified, so let the user browse for a file + if (!UserFileGet(hDlg, MappingFile)) { + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) MappingFile); + SetFocus(hCtrl); + lsplitpath(MappingFile, drive, dir, fname, ext); + } else + return FALSE; + } + + Browse = FALSE; + + // remake path so it is fully qualified + if ((drive[0] == TEXT('\0')) && (dir[0] == TEXT('\0'))) + lstrcpy(dir, ProgPath); + + if (ext[0] == TEXT('\0')) + lstrcpy(ext, Lids(IDS_S_36)); + + lmakepath(MappingFile, drive, dir, fname, ext); + + // Now make sure the file exists and is accessible + + WideCharToMultiByte(CP_ACP, 0, MappingFile, -1, FileNameA, sizeof(FileNameA), NULL, NULL); + + hFile = CreateFileA( FileNameA, GENERIC_READ, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile == INVALID_HANDLE_VALUE) { + // Couldn't open the file, report to user + if (MessageBox(hDlg, Lids(IDS_NOEDITMAP), Lids(IDS_TXTWARNING), MB_YESNO | MB_ICONQUESTION) == IDYES) + Browse = TRUE; + else { + // get out of loop as nothing more to do + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + SetFocus(hCtrl); + ret = FALSE; + } + } else { + // Could create a new file so make the mapping file... + CloseHandle(hFile); + CursorHourGlass(); + wsprintfA(CmdLine, "Notepad %s", FileNameA); + uReturn = WinExec(CmdLine, SW_SHOW); + CursorNormal(); + } + + } while (Browse); + + // Check mapping file check-box, if it's not check'd then do so + if (ret) { + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) != 1) + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + } + + return ret; + +} // MappingFileEdit + + +/*+-------------------------------------------------------------------------+ + | DlgUsers() + | + +-------------------------------------------------------------------------+*/ +LRESULT CALLBACK DlgUsers(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + int wmId, wmEvent; + static short UserNameTab, GroupNameTab, PasswordsTab, DefaultsTab; + static BOOL TrustedEnabled; + TCHAR TrustedDomain[MAX_PATH + 1]; + static TCHAR MappingFile[MAX_PATH + 1]; + DWORD dwIndex; + + switch (message) { + + case WM_INITDIALOG: + // Center the dialog over the application window + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + // Setup for Advanced >> button + ShowArea(TRUE, hDlg, GetDlgItem(hDlg, IDC_DEFAULTBOX)); + TrustedEnabled = FALSE; + + // Need to set the check and radio buttons to correct state... + UserDialogSetup(hDlg); + + hCtrl = GetDlgItem( hDlg, IDC_TABUSERS ); + + PasswordsTab = BookTab_AddItem( hCtrl, Lids(IDS_S_38) ); + BookTab_SetItemData( hCtrl, PasswordsTab, 1001 ); + + UserNameTab = BookTab_AddItem( hCtrl, Lids(IDS_S_39) ); + BookTab_SetItemData( hCtrl, UserNameTab, 1002 ); + + GroupNameTab = BookTab_AddItem( hCtrl, Lids(IDS_S_40) ); + BookTab_SetItemData( hCtrl, GroupNameTab, 1003 ); + + DefaultsTab = BookTab_AddItem( hCtrl, Lids(IDS_S_41) ); + BookTab_SetItemData( hCtrl, DefaultsTab, 1004 ); + + BookTab_SetCurSel(hCtrl, PasswordsTab); + + // now need to reset the Advanced button to the correct state and also the + // Advanced display area... + if (CurrentConvertOptions->UseTrustedDomain) { + TrustedEnabled = TRUE; + DlgUsers_TrustedSetup(hDlg); + } + + // Weirdness to initially enable controls on the tab control - + // looks like a bug in the tab control. + SetFocus(hCtrl); + hCtrl = GetDlgItem( hDlg, IDOK ); + SetFocus(hCtrl); + PostMessage(hDlg, BTN_SELCHANGE, 0, 0); + + return (TRUE); + + case BTN_SELCHANGE: + + hCtrl = GetDlgItem( hDlg, IDC_TABUSERS ); + TabSelection = BookTab_GetCurSel(hCtrl); + + if (TabSelection == UserNameTab) { + Passwords_Toggle(hDlg, FALSE); + Defaults_Toggle(hDlg, FALSE); + DuplicateGroups_Toggle(hDlg, FALSE); + DuplicateUsers_Toggle(hDlg, TRUE); + } + + if (TabSelection == GroupNameTab) { + Passwords_Toggle(hDlg, FALSE); + Defaults_Toggle(hDlg, FALSE); + DuplicateUsers_Toggle(hDlg, FALSE); + DuplicateGroups_Toggle(hDlg, TRUE); + } + + if (TabSelection == PasswordsTab) { + DuplicateUsers_Toggle(hDlg, FALSE); + Defaults_Toggle(hDlg, FALSE); + DuplicateGroups_Toggle(hDlg, FALSE); + Passwords_Toggle(hDlg, TRUE); + } + + if (TabSelection == DefaultsTab) { + Passwords_Toggle(hDlg, FALSE); + DuplicateUsers_Toggle(hDlg, FALSE); + DuplicateGroups_Toggle(hDlg, FALSE); + Defaults_Toggle(hDlg, TRUE); + } + + return (TRUE); + + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + switch (wmId) { + case IDOK: + if (UserDialogVerify(hDlg)) { + UserDialogSave(hDlg); + EndDialog(hDlg, 0); + } + + return (TRUE); + break; + + case IDCANCEL: + EndDialog(hDlg, 0); + return (TRUE); + break; + + case IDHELP: + if (TrustedEnabled) + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_USERADV); + else + WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_USER); + + return (TRUE); + break; + + case IDC_ADVANCED: + TrustedEnabled = TRUE; + DlgUsers_TrustedSetup(hDlg); + return (TRUE); + break; + + case IDC_CHKUSERS: + hCtrl = GetDlgItem(hDlg, IDC_CHKUSERS); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + UserDialogToggle(hDlg, TRUE); + else + UserDialogToggle(hDlg, FALSE); + + PostMessage(hDlg, BTN_SELCHANGE, 0, 0); + return (TRUE); + break; + + case IDC_CHKMAPPING: + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) + Mapping_Toggle(hDlg, FALSE); + else + Mapping_Toggle(hDlg, TRUE); + + return (TRUE); + break; + + case IDC_CHKTRUSTED: + hCtrl = GetDlgItem(hDlg, IDC_CHKTRUSTED); + if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == 1) { + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, TRUE); + + // Get trusted domain + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0); + if (dwIndex != CB_ERR) { + // Get the domain name and then try to add it to our lists + SendMessage(hCtrl, CB_GETLBTEXT, (WPARAM) dwIndex, (LPARAM) TrustedDomain); + CurrentConvertOptions->TrustedDomain = NTTrustedDomainSet(hDlg, DestServ, TrustedDomain); + CurrentConvertOptions->UseTrustedDomain = TRUE; + } else + CurrentConvertOptions->UseTrustedDomain = FALSE; + + } else { + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, FALSE); + CurrentConvertOptions->UseTrustedDomain = FALSE; + } + + // Toggled trust relationship so setup FPNW info accordingly + FPNWChk = IsFPNW(UserServerNameGet(DServ, CurrentConvertOptions)); + if (TabSelection == DefaultsTab) + Defaults_Toggle(hDlg, TRUE); + + return (TRUE); + break; + + case IDC_TRUSTED: + if (wmEvent == CBN_SELCHANGE) { + // A new trusted domain was selected, update FPNW flag + hCtrl = GetDlgItem(hDlg, IDC_TRUSTED); + EnableWindow(hCtrl, TRUE); + + // Get trusted domain + dwIndex = SendMessage(hCtrl, CB_GETCURSEL, 0, 0); + if (dwIndex != CB_ERR) { + // Get the domain name and then try to add it to our lists + SendMessage(hCtrl, CB_GETLBTEXT, (WPARAM) dwIndex, (LPARAM) TrustedDomain); + CurrentConvertOptions->TrustedDomain = NTTrustedDomainSet(hDlg, DestServ, TrustedDomain); + CurrentConvertOptions->UseTrustedDomain = TRUE; + } else + CurrentConvertOptions->UseTrustedDomain = FALSE; + + FPNWChk = IsFPNW(UserServerNameGet(DServ, CurrentConvertOptions)); + CurrentConvertOptions->NetWareInfo = FPNWChk; + + if (TabSelection == DefaultsTab) + Defaults_Toggle(hDlg, TRUE); + + } + break; + + case IDC_BTNMAPPINGFILE: + // Get anything in the text box + hCtrl = GetDlgItem(hDlg, IDC_MAPPINGFILE); + * (WORD *)MappingFile = sizeof(MappingFile); + SendMessage(hCtrl, EM_GETLINE, 0, (LPARAM) MappingFile); + + // invoke the creation routine + MapFileCreate(hDlg, MappingFile, SourceServ); + + // reset edit-box to whatever the returned filename is + SendMessage(hCtrl, WM_SETTEXT, 0, (LPARAM) MappingFile); + + if (SendMessage(hCtrl, EM_LINELENGTH, 0, 0)) { + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + SendMessage(hCtrl, BM_SETCHECK, 1, 0); + } else { + hCtrl = GetDlgItem(hDlg, IDC_CHKMAPPING); + SendMessage(hCtrl, BM_SETCHECK, 0, 0); + } + + return (TRUE); + break; + + case IDC_BTNMAPPINGEDIT: + MappingFileEdit(hDlg); + return (TRUE); + break; + + case IDC_PWCONST: + + if (wmEvent == EN_CHANGE) + CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO3); + + break; + + case IDC_USERCONST: + + if (wmEvent == EN_CHANGE) + CheckRadioButton(hDlg, IDC_RADIO4, IDC_RADIO7, IDC_RADIO7); + + break; + + case IDC_GROUPCONST: + + if (wmEvent == EN_CHANGE) + CheckRadioButton(hDlg, IDC_RADIO8, IDC_RADIO10, IDC_RADIO10); + + break; + + } + break; + } + + return (FALSE); // Didn't process the message + + lParam; +} // DlgUsers + + + +/*+-------------------------------------------------------------------------+ + | UserOptions_Do() + | + +-------------------------------------------------------------------------+*/ +void UserOptions_Do(HWND hDlg, void *ConvOptions, SOURCE_SERVER_BUFFER *SourceServer, DEST_SERVER_BUFFER *DestServer) { + DLGPROC lpfnDlg; + + SServ = SourceServer; + DServ = DestServer; + SourceServ = SourceServer->Name; + DestServ = DestServer->Name; + + FPNWChk = DServ->IsFPNW; + CurrentConvertOptions = (CONVERT_OPTIONS *) ConvOptions; + lpfnDlg = MakeProcInstance((DLGPROC)DlgUsers, hInst); + DialogBox(hInst, TEXT("DlgNewUsers"), hDlg, lpfnDlg) ; + FreeProcInstance(lpfnDlg); +} // UserOptions_Do + diff --git a/private/nw/convert/nwconv/userdlg.h b/private/nw/convert/nwconv/userdlg.h new file mode 100644 index 000000000..dcb91d6a0 --- /dev/null +++ b/private/nw/convert/nwconv/userdlg.h @@ -0,0 +1,49 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _USERDLG_ +#define _USERDLG_ + +#ifdef __cplusplus +extern "C"{ +#endif + + +typedef struct _CONVERT_OPTIONS { + BOOL TransferUserInfo; + + BOOL UseMappingFile; + TCHAR MappingFile[MAX_PATH + 1]; + + int PasswordOption; + TCHAR PasswordConstant[MAX_PW_LEN + 1]; + BOOL ForcePasswordChange; + + int UserNameOption; + TCHAR UserConstant[MAX_UCONST_LEN + 1]; + + int GroupNameOption; + TCHAR GroupConstant[MAX_UCONST_LEN + 1]; + + BOOL SupervisorDefaults; + BOOL AdminAccounts; + BOOL NetWareInfo; + + BOOL UseTrustedDomain; + DOMAIN_BUFFER *TrustedDomain; +} CONVERT_OPTIONS; + +void UserOptionsDefaultsSet(void *cvto); +void UserOptionsDefaultsReset(); +void UserOptionsInit(void **cvto); +void UserOptionsLoad(HANDLE hFile, void **lpcvto); +void UserOptionsSave(HANDLE hFile, void *cvto); + +void UserOptions_Do(HWND hDlg, void *ConvOptions, SOURCE_SERVER_BUFFER *SourceServer, DEST_SERVER_BUFFER *DestServer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/usrprop.c b/private/nw/convert/nwconv/usrprop.c new file mode 100644 index 000000000..c52603ee0 --- /dev/null +++ b/private/nw/convert/nwconv/usrprop.c @@ -0,0 +1,592 @@ +/*++ + +Copyright (c) 1993-1993 Microsoft Corporation + +Module Name: + + usrprop.c + +Abstract: + + This module implements QueryUserProperty() and SetUserProperty() + which read and write NetWare Properties to the UserParms field. + +Author: + + Andy Herron (andyhe) 24-May-1993 + Congpa You (CongpaY) 28-Oct-1993 Seperated SetUserProperty() and + QueryUserProperty() out from usrprop.c + in ncpsrv\svcdlls\ncpsvc\libbind, + modified the code and fixed a few + existing problems. + +Revision History: + +--*/ + +#include "nt.h" +#include "ntrtl.h" +#include "nturtl.h" +#include "ntioapi.h" +#include "windef.h" +#include "winbase.h" +#include "stdio.h" +#include "stdlib.h" +#include "winuser.h" + +#include "usrprop.h" + +#define NCP_SET 0x02 /* Series of Object ID numbers, each 4 + bytes long */ + +// +// All internal (opaque) structures are listed here since no one else +// needs to reference them. +// + +// +// The user's Parameter field is mapped out to a structure that contains +// the backlevel 48 WCHARs for Mac/Ras compatibility plus a new structure +// that is basically an array of chars that make up a property name plus +// a property value. +// + +// +// This is the structure for an individual property. Note that there are +// no null terminators in this. +// +typedef struct _USER_PROPERTY { + WCHAR PropertyLength; // length of property name + WCHAR ValueLength; // length of property value + WCHAR PropertyFlag; // type of property (1 = set, 2 = item) + WCHAR Property[1]; // start of property name, followed by value +} USER_PROPERTY, *PUSER_PROPERTY; + +// +// This is the structure that maps the beginning of the user's Parameters +// field. It is only separate so that we can do a sizeof() without including +// the first property, which may or may not be there. +// + +typedef struct _USER_PROPERTIES_HDR { + WCHAR BacklevelParms[48]; // RAS & Mac data stored here. + WCHAR PropertySignature; // signature that we can look for. + WCHAR PropertyCount; // number of properties present. +} USER_PROPERTIES_HDR, *PUSER_PROPERTIES_HDR; + +// +// This structure maps out the whole of the user's Parameters field when +// the user properties structure is present and at least one property is +// defined. +// + +typedef struct _USER_PROPERTIES { + USER_PROPERTIES_HDR Header; + USER_PROPERTY FirstProperty; +} USER_PROPERTIES, *PUSER_PROPERTIES; + +// +// forward references +// + +NTSTATUS +UserPropertyAllocBlock ( + IN PUNICODE_STRING Existing, + IN ULONG DesiredLength, + IN OUT PUNICODE_STRING New + ); + +BOOL +FindUserProperty ( + PUSER_PROPERTIES UserProperties, + LPWSTR Property, + PUSER_PROPERTY *pUserProperty, + USHORT *pCount + ); + +VOID +RemoveUserProperty ( + UNICODE_STRING *puniUserParms, + PUSER_PROPERTY UserProperty, + USHORT Count, + BOOL *Update + ); + +NTSTATUS +SetUserProperty ( + IN LPWSTR UserParms, + IN LPWSTR Property, + IN UNICODE_STRING PropertyValue, + IN WCHAR PropertyFlag, + OUT LPWSTR *pNewUserParms, // memory has to be freed afer use. + OUT BOOL *Update + ) +/* + This function sets a property field in the user's Parameters field. +*/ +{ + NTSTATUS status; + UNICODE_STRING uniUserParms; + UNICODE_STRING uniNewUserParms; + USHORT Count = 0; + USHORT PropertyLength; + USHORT ValueLength; + PUSER_PROPERTIES UserProperties; + PUSER_PROPERTY UserProperty; + LPWSTR PropertyValueString = NULL; + INT i; + UCHAR *pchValue = NULL; + + // Check if parameters are correct. + if (Property == NULL) + { + return( STATUS_INVALID_PARAMETER ); + } + + // Initialize output variables. + *Update = FALSE; + *pNewUserParms = NULL; + + // Converty UserParms to unicode string. + uniUserParms.Buffer = UserParms; + uniUserParms.Length = UserParms? (lstrlenW(UserParms) + 1)* sizeof (WCHAR) + : 0; + uniUserParms.MaximumLength = uniUserParms.Length; + + /** Get the length of the property name **/ + + PropertyLength = lstrlenW( Property ) * sizeof(WCHAR); + + /** Get the length of the property value **/ + ValueLength = PropertyValue.Length; + + if (ValueLength != 0) + { + // Converty property value to asci string so that + // if property value is 0, it can be stored correctly. + + PropertyValueString = (LPWSTR) LocalAlloc (LPTR, (ValueLength+1)*sizeof (WCHAR)); + + pchValue = (UCHAR *) PropertyValue.Buffer; + + // BUGBUG. Since wsprint converts 0x00 to 20 30 (20 is + // space and 30 is 0), sscanf converts 20 30 to 0. If the + // value is uncode string, this convertsion would not + // convert back to original value. So if we want to store + // some value in the UserParms, we have to pass in ansi + // string. + + for (i = 0; i < ValueLength; i++) + { + wsprintfA ((PCHAR)(PropertyValueString+i), "%02x", *(pchValue+i)); + } + + *(PropertyValueString+ValueLength) = 0; + ValueLength = ValueLength * sizeof (WCHAR); + } + + // + // check that user has valid property structure , if not, create one + // + + if (UserParms != NULL) + { + Count = (lstrlenW (UserParms) + 1)* sizeof(WCHAR); + } + + if (Count < sizeof( USER_PROPERTIES)) + { + Count = sizeof( USER_PROPERTIES_HDR ) + sizeof(WCHAR); + } + + if (ValueLength > 0) + { + Count += sizeof( USER_PROPERTY ) + PropertyLength + ValueLength; + } + + if (Count > 0x7FFF) + { + // can't be bigger than 32K of user parms. + return (STATUS_BUFFER_OVERFLOW); + } + + status = UserPropertyAllocBlock( &uniUserParms, + Count, + &uniNewUserParms ); + + if ( !NT_SUCCESS(status) ) + { + return status; + } + + // Make the output pNewUserParms point to uniNewUserPams's buffer + // which is the new UserParms string. + + *pNewUserParms = uniNewUserParms.Buffer; + + UserProperties = (PUSER_PROPERTIES) uniNewUserParms.Buffer; + + if (FindUserProperty (UserProperties, + Property, + &UserProperty, + &Count)) + { + RemoveUserProperty ( &uniNewUserParms, + UserProperty, + Count, + Update); + } + + // + // If the new value of the property is not null, add it. + // + + if (ValueLength > 0) { + + // find the end of the parameters list + + UserProperty = &(UserProperties->FirstProperty); + + for (Count = 1; Count <= UserProperties->Header.PropertyCount; Count++) + { + UserProperty = (PUSER_PROPERTY) + ((LPSTR)((LPSTR) UserProperty + + sizeof(USER_PROPERTY) + // length of entry + UserProperty->PropertyLength + + UserProperty->ValueLength - + sizeof(WCHAR))); // for Property[0] + } + + // + // append it to the end and update length of string + // + + UserProperty->PropertyFlag = (PropertyFlag & NCP_SET) ? + USER_PROPERTY_TYPE_SET : + USER_PROPERTY_TYPE_ITEM; + + UserProperty->PropertyLength = PropertyLength; + UserProperty->ValueLength = ValueLength; + + RtlCopyMemory( &(UserProperty->Property[0]), + Property, + PropertyLength ); + + RtlCopyMemory( &(UserProperty->Property[PropertyLength / sizeof(WCHAR)]), + PropertyValueString, + ValueLength ); + + uniNewUserParms.Length += + sizeof(USER_PROPERTY) + // length of entry + PropertyLength + // length of property name string + ValueLength - // length of value string + sizeof(WCHAR); // account for WCHAR Property[1] + + UserProperties->Header.PropertyCount++; + + *Update = TRUE; + } + + // UserParms is already null terminated. We don't need to set the + // end of UserParms to be NULL since we zero init the buffer already. + + return( status ); +} // SetUserProperty + +#define MAPHEXTODIGIT(x) ( x >= '0' && x <= '9' ? (x-'0') : \ + x >= 'A' && x <= 'F' ? (x-'A'+10) : \ + x >= 'a' && x <= 'f' ? (x-'a'+10) : 0 ) + + +NTSTATUS +QueryUserProperty ( + IN LPWSTR UserParms, + IN LPWSTR PropertyName, + OUT PWCHAR PropertyFlag, + OUT PUNICODE_STRING PropertyValue + ) +/* + This routine returns a user definable property value as it is stored + in the user's Parameters field. Note that the RAS/MAC fields are + stripped before we start processing user properties. +*/ +{ + USHORT PropertyNameLength; + USHORT Count; + PUSER_PROPERTY UserProperty; + WCHAR *Value; + UINT i; + CHAR *PropertyValueString; + CHAR *pchValue; + + // Set PropertyValue->Length to 0 initially. If the property is not found + // it will still be 0 on exit. + + PropertyValue->Length = 0; + PropertyValue->Buffer = NULL; + + PropertyNameLength = lstrlenW(PropertyName) * sizeof(WCHAR); + + // Check if UserParms have the right structure. + + if (FindUserProperty ((PUSER_PROPERTIES) UserParms, + PropertyName, + &UserProperty, + &Count) ) + { + + Value = (LPWSTR)(LPSTR)((LPSTR) &(UserProperty->Property[0]) + + PropertyNameLength); + + // + // Found the requested property + // + + // + // Copy the property flag. + // + + if (PropertyFlag) + *PropertyFlag = UserProperty->PropertyFlag; + + // Allocate memory for PropertyValue->Buffer + + PropertyValueString = LocalAlloc ( LPTR, UserProperty->ValueLength+1); + PropertyValue->Buffer = LocalAlloc ( LPTR, UserProperty->ValueLength/sizeof(WCHAR)); + + // + // Make sure the property value length is valid. + // + if ((PropertyValue->Buffer == NULL) || (PropertyValueString == NULL)) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // Copy the property value to the buffer. + // + + RtlCopyMemory( PropertyValueString, + Value, + UserProperty->ValueLength ); + + pchValue = (CHAR *) PropertyValue->Buffer; + + // Convert from value unicode string to value. + for (i = 0; i < UserProperty->ValueLength/sizeof(WCHAR) ; i++) + { + // sscanf will trash memory. + // sscanf( PropertyValueString+2*i, "%2x", pchValue+i); + + pchValue[i] = MAPHEXTODIGIT( PropertyValueString[2*i]) * 16 + + MAPHEXTODIGIT( PropertyValueString[2*i+1]); + } + + PropertyValue->Length = UserProperty->ValueLength/sizeof(WCHAR); + PropertyValue->MaximumLength = UserProperty->ValueLength/sizeof(WCHAR); + + LocalFree( PropertyValueString); + } + + return STATUS_SUCCESS; +} // QueryUserProperty + + +// Common routine used by QueryUserProperty() and SetUserProperty(). + +BOOL +FindUserProperty ( + PUSER_PROPERTIES UserProperties, + LPWSTR Property, + PUSER_PROPERTY *pUserProperty, + USHORT *pCount + ) +{ + BOOL fFound = FALSE; + USHORT PropertyLength; + + // + // Check if user has valid property structure attached, + // pointed to by UserProperties. + // + + if ( ( UserProperties != NULL ) + && ( lstrlenW( (LPWSTR) UserProperties) * sizeof(WCHAR) > + sizeof(UserProperties->Header.BacklevelParms)) + && ( UserProperties->Header.PropertySignature == USER_PROPERTY_SIGNATURE) + ) + { + // + // user has valid property structure. + // + + *pUserProperty = &(UserProperties->FirstProperty); + + PropertyLength = lstrlenW( Property ) * sizeof(WCHAR); + + for ( *pCount = 1; *pCount <= UserProperties->Header.PropertyCount; + (*pCount)++ ) + { + if ( ( PropertyLength == (*pUserProperty)->PropertyLength ) + && ( RtlCompareMemory( &((*pUserProperty)->Property[0]), + Property, + PropertyLength ) == PropertyLength ) + ) + { + fFound = TRUE; + break; + } + + *pUserProperty = (PUSER_PROPERTY) + ((LPSTR) (*pUserProperty) + + sizeof( USER_PROPERTY ) + + (*pUserProperty)->PropertyLength + + (*pUserProperty)->ValueLength + - sizeof(WCHAR)); // for Property[0] + } + } + + return( fFound ); +} // FindUserProperty + + +// Remove a property field from the User Parms. + +VOID +RemoveUserProperty ( + UNICODE_STRING *puniUserParms, + PUSER_PROPERTY UserProperty, + USHORT Count, + BOOL *Update + ) +{ + PUSER_PROPERTIES UserProperties; + PUSER_PROPERTY NextProperty; + USHORT OldParmLength; + + UserProperties = (PUSER_PROPERTIES) puniUserParms->Buffer; + + OldParmLength = sizeof( USER_PROPERTY ) + + UserProperty->PropertyLength + + UserProperty->ValueLength - + sizeof(WCHAR); // for Property[0] + + + NextProperty = (PUSER_PROPERTY)(LPSTR)((LPSTR) UserProperty + OldParmLength); + + // + // if we're not on the last one, copy the remaining buffer up + // + + if (Count < UserProperties->Header.PropertyCount) { + + RtlMoveMemory( UserProperty, + NextProperty, + puniUserParms->Length - + ((LPSTR) NextProperty - + (LPSTR) puniUserParms->Buffer )); + } + + // + // Now reduce the length of the buffer by the amount we pulled out + // + + puniUserParms->Length -= OldParmLength; + + UserProperties->Header.PropertyCount--; + + *Update = TRUE; +} // RemoveUserProperty + + +NTSTATUS +UserPropertyAllocBlock ( + IN PUNICODE_STRING Existing, + IN ULONG DesiredLength, + IN OUT PUNICODE_STRING New + ) +/* + This allocates a larger block for user's parameters and copies the old + block in. +*/ +{ + PUSER_PROPERTIES UserProperties; + CLONG Count; + WCHAR *pNewBuff; + + + // + // We will allocate a new buffer to store the new parameters + // and copy the existing parameters into it. + // + + New->Buffer = LocalAlloc (LPTR, DesiredLength); + + if ( New->Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + New->MaximumLength = (USHORT) DesiredLength; + + if (Existing != NULL) + { + + New->Length = Existing->Length; + + RtlCopyMemory( New->Buffer, + Existing->Buffer, + Existing->Length ); + } + else + { + New->Length = 0; + } + + // + // Ensure that we don't have any nulls in our string. + // + + for ( Count = 0; + Count < New->Length / sizeof(WCHAR); + Count++ ) + { + if (*(New->Buffer + Count) == L'\0') + { + New->Length = (USHORT) Count * sizeof(WCHAR); + break; + } + } + + // + // now pad it out with spaces until reached Mac+Ras reserved length + // + + pNewBuff = (WCHAR *) New->Buffer + ( New->Length / sizeof(WCHAR) ); + + while ( New->Length < sizeof(UserProperties->Header.BacklevelParms)) + { + *( pNewBuff++ ) = L' '; + New->Length += sizeof(WCHAR); + } + + // + // If the signature isn't there, stick it in and set prop count to 0 + // + + UserProperties = (PUSER_PROPERTIES) New->Buffer; + + if (New->Length < sizeof(USER_PROPERTIES_HDR) || + UserProperties->Header.PropertySignature != USER_PROPERTY_SIGNATURE) + { + + UserProperties->Header.PropertySignature = USER_PROPERTY_SIGNATURE; + UserProperties->Header.PropertyCount = 0; + + New->Length = sizeof(USER_PROPERTIES_HDR); + } + + return STATUS_SUCCESS; +} // UserPropertyAllocBlock + +// usrprop.c eof. diff --git a/private/nw/convert/nwconv/usrprop.h b/private/nw/convert/nwconv/usrprop.h new file mode 100644 index 000000000..6c7dbb6e8 --- /dev/null +++ b/private/nw/convert/nwconv/usrprop.h @@ -0,0 +1,77 @@ +/*++ + +Copyright (c) 1993 Micro Computer Systems, Inc. + +Module Name: + + usrprop.h + +Abstract: + + This is the public include file for some of the functions used by + User Manager and Server Manager. + +Author: + + Congpa You 02-Dec-1993 Created. + +Revision History: + +--*/ + +#ifndef _USRPROP_H_ +#define _USRPROP_H_ + +#define USER_PROPERTY_SIGNATURE L'P' + +#define NWPASSWORD L"NWPassword" +#define OLDNWPASSWORD L"OldNWPassword" +#define MAXCONNECTIONS L"MaxConnections" +#define NWTIMEPASSWORDSET L"NWPasswordSet" +#define SZTRUE L"TRUE" +#define GRACELOGINALLOWED L"GraceLoginAllowed" +#define GRACELOGINREMAINING L"GraceLoginRemaining" +#define NWLOGONFROM L"NWLogonFrom" +#define NWHOMEDIR L"NWHomeDir" +#define NW_PRINT_SERVER_REF_COUNT L"PSRefCount" + +#define NWENCRYPTEDPASSWORDLENGTH 8 + +#define NO_LIMIT 0xffff + +#define DEFAULT_MAXCONNECTIONS NO_LIMIT +#define DEFAULT_NWPASSWORDEXPIRED FALSE +#define DEFAULT_GRACELOGINALLOWED 6 +#define DEFAULT_GRACELOGINREMAINING 6 +#define DEFAULT_NWLOGONFROM NULL +#define DEFAULT_NWHOMEDIR NULL + +#define USER_PROPERTY_TYPE_ITEM 1 +#define USER_PROPERTY_TYPE_SET 2 + +//Encryption function +NTSTATUS ReturnNetwareForm (const char * pszSecretValue, + DWORD dwUserId, + const WCHAR * pchNWPassword, + UCHAR * pchEncryptedNWPassword); + +NTSTATUS +SetUserProperty( + IN LPWSTR UserParms, + IN LPWSTR Property, + IN UNICODE_STRING PropertyValue, + IN WCHAR PropertyFlag, + OUT LPWSTR * pNewUserParms, // memory has to be freed after use. + OUT BOOL * Update + ); + +NTSTATUS +QueryUserProperty ( + IN LPWSTR UserParms, + IN LPWSTR Property, + OUT PWCHAR PropertyFlag, + OUT PUNICODE_STRING PropertyValue + ); + +#endif // _USRPROP_H_ + 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: | + | 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 ; + } +} + + diff --git a/private/nw/convert/nwconv/utils.h b/private/nw/convert/nwconv/utils.h new file mode 100644 index 000000000..bc2944862 --- /dev/null +++ b/private/nw/convert/nwconv/utils.h @@ -0,0 +1,33 @@ +/*+-------------------------------------------------------------------------+ + | Copyright 1993-1994 (C) Microsoft Corporation - All rights reserved. | + +-------------------------------------------------------------------------+*/ + +#ifndef _UTILS_ +#define _UTILS_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#define MAX_DRIVE 30 + +LPTSTR Lids(WORD idsStr); +void StringTableDestroy(); +void CursorHourGlass(); +void CursorNormal(); +BOOL BitTest(int Bit, BYTE *Bits); +BOOL CenterWindow( HWND hwndChild, HWND hwndParent ); +TCHAR *lstrchr(LPTSTR String, TCHAR c); +BOOL IsPath(LPTSTR Path); +LPTSTR lToStr(ULONG Number); +LPTSTR TimeToStr(ULONG TotTime); +void EscapeFormattingChars(LPTSTR String, ULONG BufferLength) ; + +void lsplitpath(const TCHAR *path, TCHAR *drive, TCHAR *dir, TCHAR *fname, TCHAR *ext); +void lmakepath(TCHAR *path, const TCHAR *drive, const TCHAR *dir, const TCHAR *fname, const TCHAR *ext); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/private/nw/convert/nwconv/version.h b/private/nw/convert/nwconv/version.h new file mode 100644 index 000000000..2d4116ea1 --- /dev/null +++ b/private/nw/convert/nwconv/version.h @@ -0,0 +1,52 @@ +/* +** Template for version resources. Place this in your .rc file, +** editing the values for VER_FILETYPE, VER_FILESUBTYPE, +** VER_FILEDESCRIPTION_STR and VER_INTERNALNAME_STR as needed. +** See winver.h for possible values. +** +** Ntverp.h defines several global values that don't need to be +** changed except for official releases such as betas, sdk updates, etc. +** +** Common.ver has the actual version resource structure that all these +** #defines eventually initialize. +*/ + +/* #include needed if this will be the .rc file */ + +#include + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR + * and VER_INTERNALNAME_STR must be defined before including COMMON.VER + * The strings don't need a '\0', since common.ver has them. + */ +#define VER_FILETYPE VFT_APP +/* possible values: VFT_UNKNOWN + VFT_APP + VFT_DLL + VFT_DRV + VFT_FONT + VFT_VXD + VFT_STATIC_LIB +*/ +#define VER_FILESUBTYPE VFT2_UNKNOWN +/* possible values VFT2_UNKNOWN + VFT2_DRV_PRINTER + VFT2_DRV_KEYBOARD + VFT2_DRV_LANGUAGE + VFT2_DRV_DISPLAY + VFT2_DRV_MOUSE + VFT2_DRV_NETWORK + VFT2_DRV_SYSTEM + VFT2_DRV_INSTALLABLE + VFT2_DRV_SOUND + VFT2_DRV_COMM +*/ +#define VER_FILEDESCRIPTION_STR "Migration Tool for NetWare" +#define VER_INTERNALNAME_STR "NWConv" +#define VER_ORIGINALFILENAME_STR "NWCONV.EXE" + +#include "common.ver" diff --git a/private/nw/convert/nwconv/vlist.h b/private/nw/convert/nwconv/vlist.h new file mode 100644 index 000000000..8fffae07f --- /dev/null +++ b/private/nw/convert/nwconv/vlist.h @@ -0,0 +1,95 @@ +#define VLB_OK 0 +#define VLB_ERR -1 +#define VLB_ENDOFFILE -1 + +#define VLBS_USEDATAVALUES 0x8000L +#define VLBS_3DFRAME 0x4000L +#define VLBS_NOTIFY 0x0001L +#define VLBS_NOREDRAW 0x0004L +#define VLBS_OWNERDRAWFIXED 0x0010L +#define VLBS_HASSTRINGS 0x0040L +#define VLBS_USETABSTOPS 0x0080L +#define VLBS_NOINTEGRALHEIGHT 0x0100L +#define VLBS_WANTKEYBOARDINPUT 0x0400L +#define VLBS_DISABLENOSCROLL 0x1000L + +// Application->VLIST messages +// Corresponding to LB_ messages +#define VLB_RESETCONTENT (WM_USER+500) +#define VLB_SETCURSEL (WM_USER+501) +#define VLB_GETCURSEL (WM_USER+502) +#define VLB_GETTEXT (WM_USER+503) +#define VLB_GETTEXTLEN (WM_USER+504) +#define VLB_GETCOUNT (WM_USER+505) +#define VLB_SELECTSTRING (WM_USER+506) +#define VLB_FINDSTRING (WM_USER+507) +#define VLB_GETITEMRECT (WM_USER+508) +#define VLB_GETITEMDATA (WM_USER+509) +#define VLB_SETITEMDATA (WM_USER+510) +#define VLB_SETITEMHEIGHT (WM_USER+511) +#define VLB_GETITEMHEIGHT (WM_USER+512) +#define VLB_FINDSTRINGEXACT (WM_USER+513) +#define VLB_INITIALIZE (WM_USER+514) +#define VLB_SETTABSTOPS (WM_USER+515) +#define VLB_GETTOPINDEX (WM_USER+516) +#define VLB_SETTOPINDEX (WM_USER+517) +#define VLB_GETHORIZONTALEXTENT (WM_USER+518) +#define VLB_SETHORIZONTALEXTENT (WM_USER+519) + +// Unique to VLIST +#define VLB_UPDATEPAGE (WM_USER+520) +#define VLB_GETLINES (WM_USER+521) +#define VLB_GETSCROLLPOS (WM_USER+522) +#define VLB_HSCROLL (WM_USER+523) +#define VLB_PAGEDOWN (WM_USER+524) +#define VLB_PAGEUP (WM_USER+525) +#define VLB_GETLISTBOXSTYLE (WM_USER+526) +#define VLB_GETFOCUSHWND (WM_USER+527) +#define VLB_GETVLISTSTYLE (WM_USER+528) + +#define VLB_TOVLIST_MSGMIN VLB_RESETCONTENT +#define VLB_TOVLIST_MSGMAX VLB_GETVLISTSTYLE + +// VLIST->Application messages +// Conflicts with VLB_ +#define VLBR_FINDSTRING (WM_USER+600) +#define VLBR_FINDSTRINGEXACT (WM_USER+601) +#define VLBR_SELECTSTRING (WM_USER+602) +#define VLBR_GETITEMDATA (WM_USER+603) +#define VLBR_GETTEXT (WM_USER+604) +#define VLBR_GETTEXTLEN (WM_USER+605) + +// Unique Messages +// +#define VLB_FIRST (WM_USER+606) +#define VLB_PREV (WM_USER+607) +#define VLB_NEXT (WM_USER+608) +#define VLB_LAST (WM_USER+609) +#define VLB_FINDITEM (WM_USER+610) +#define VLB_RANGE (WM_USER+611) +#define VLB_FINDPOS (WM_USER+612) +#define VLB_DONE (WM_USER+613) + +// VLIST->Application Notifications +#define VLBN_FREEITEM (WM_USER+700) +#define VLBN_FREEALL (WM_USER+701) + +#define VLB_TOAPP_MSGMIN VLB_FINDSTRING +#define VLB_TOAPP_MSGMAX VLBN_FREEALL + +#define IDS_VLBOXNAME 1 + +typedef struct _VLBStruct { + int nCtlID; + int nStatus; + LONG lData; // current data value + LONG lIndex; // current index + LONG lSelItem; // current selection (if data value) + LPTSTR lpTextPointer; + LPTSTR lpFindString; +} VLBSTRUCT; + +typedef VLBSTRUCT FAR* LPVLBSTRUCT; + +#define VLIST_CLASSNAME "VList" +extern BOOL WINAPI RegisterVListBox(HINSTANCE); diff --git a/private/nw/convert/nwconv/vlistint.h b/private/nw/convert/nwconv/vlistint.h new file mode 100644 index 000000000..bd037a175 --- /dev/null +++ b/private/nw/convert/nwconv/vlistint.h @@ -0,0 +1,89 @@ +#include "windows.h" +#include "windowsx.h" +#include "vlist.h" + +typedef struct tagVLISTBox + { + HWND hwnd; // hwnd of this VLIST box + int nId; // Id of Control + HINSTANCE hInstance; // Instance of parent + HWND hwndParent; // hwnd of parent of VLIST box + HWND hwndList; // hwnd of List box + WNDPROC lpfnLBWndProc; // Window procedure of list box + int nchHeight; // Height of text line + int nLines; // Number of lines in listbox + LONG styleSave; // Save the Style Bits + WORD VLBoxStyle; // List Box Style + HANDLE hFont; // Font for List box + LONG lToplIndex; // Top logical record number; + int nCountInBox; // Number of Items in box. + LONG lNumLogicalRecs; // Number of logical records + VLBSTRUCT vlbStruct; // Buffer to communicate to app + WORD wFlags; // Various flags fot the VLB + // + // 0x01 - HasStrings + // 0x02 - Use Data Values + // 0x04 - Multiple Selections + // 0x08 - Ok for parent to have focus + // 0x10 - Control has focus + + LONG lSelItem; // List of selected items + int nvlbRedrawState; // Redraw State + BOOL bHScrollBar; // Does it have a H Scroll +} VLBOX; + +typedef VLBOX NEAR *PVLBOX; +typedef VLBOX FAR *LPVLBOX; + + +#define IDS_VLBOXNAME 1 +#define VLBLBOXID 100 +#define VLBEDITID 101 + +#define HASSTRINGS 0x01 // List box stores strings +#define USEDATAVALUES 0x02 // Use Data Values to talk to parent +#define MULTIPLESEL 0x04 // VLB has extended or multiple selection +#define PARENTFOCUS 0x08 // Ok for parent to have focus +#define HASFOCUS 0x10 // 0x10 - Control has focus + +LRESULT CALLBACK VListBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK LBSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LONG VLBMessageItemHandler( PVLBOX pVLBox, UINT message, LPTSTR lpfoo); +LONG VLBParentMessageHandler( PVLBOX pVLBox, UINT message, WPARAM wParam, LPARAM lParam); +LONG VLBNcCreateHandler( HWND hwnd, LPCREATESTRUCT lpcreateStruct); +LONG VLBCreateHandler( PVLBOX pVListBox, HWND hwnd, LPCREATESTRUCT lpcreateStruct); +void VLBNcDestroyHandler(HWND hwnd, PVLBOX pVListBox, WPARAM wParam, LPARAM lParam); +void VLBDestroyHandler(HWND hwnd, PVLBOX pVLBox, WPARAM wParam, LPARAM lParam); +void VLBSetFontHandler( PVLBOX pVListBox, HANDLE hFont, BOOL fRedraw); +int VLBScrollDownLine( PVLBOX pVLBox); +int VLBScrollUpLine( PVLBOX pVLBox); +int VLBScrollDownPage( PVLBOX pVLBox, int nAdjustment); +int VLBScrollUpPage( PVLBOX pVLBox, int nAdjustment); +void UpdateVLBWindow( PVLBOX pVLBox, LPRECT lpRect); +int VLBFindPos( PVLBOX pVLBox, int nPos); +int VLBFindPage( PVLBOX pVLBox, LONG lFindRecNum, BOOL bUpdateTop); +int VLBFirstPage( PVLBOX pVLBox); +int VLBLastPage( PVLBOX pVLBox); +LONG vlbSetCurSel( PVLBOX pVLBox, int nOption, LONG lParam); +int vlbFindData( PVLBOX pVLBox, LONG lData); +void VLBSizeHandler( PVLBOX pVLBox, int nItemHeight); +int vlbInVLB( PVLBOX pVLBox, LONG lData); +void VLBCountLines( PVLBOX pVLBox); + +void vlbRedrawOff(PVLBOX pVLBox); +void vlbRedrawOn(PVLBOX pVLBox); + +BOOL TestSelectedItem(PVLBOX pVLBox, VLBSTRUCT vlbStruct); +void SetSelectedItem(PVLBOX pVLBox); + +void vlbPGDN(PVLBOX pVLBox); +void vlbPGUP(PVLBOX pVLBox); + +void vlbLineDn(PVLBOX pVLBox); +void vlbLineUp(PVLBOX pVLBox); + +void VLBFreeItem(PVLBOX pVLBox, long lFreeItem); +void VLBFreePage(PVLBOX pVLBox); + +extern HANDLE hInstance; // Global instance handle for DLL -- cgit v1.2.3