|
|
/*
+-------------------------------------------------------------------------+ | 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
|