NT4/private/nw/convert/nwconv/map.c

1683 lines
48 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*
+-------------------------------------------------------------------------+
| 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