/* ======================================================================================= Name : VssFunct.cpp Author : vincent lhullier Date :27/07/97 Description : Manage vss tree, file of list to obtain ======================================================================================= Modification -> Author : Date : Description : ======================================================================================= */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include "stdafx.h" #include #include "Tree_Fct.h" #include "IniData.h" /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* ======================================================================================= GLOBALS ======================================================================================= */ tdstProject *g_p_stRootProject = NULL; char g_szFullName[MAX_PATH]; char **gs_d_szFile; char **gs_d_szProj; /* * globals for list of extension */ long g_lNumberOfFileTypes = 0; long g_lNumberMaxOfFileTypes = 0; tdstFileType *g_d_stFileType = NULL; HWND g_hProjectWindow; /* ======================================================================================= File type functions ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : free list of file type ---------------------------------------------------------------------------------------- */ void fn_Tree_vFreeFileTypeList( void ) { if (g_lNumberMaxOfFileTypes != 0) { free ( g_d_stFileType ); g_d_stFileType = NULL; g_lNumberOfFileTypes = 0; g_lNumberMaxOfFileTypes = 0; } } /* ---------------------------------------------------------------------------------------- Description : search if a file type is in list or not ---------------------------------------------------------------------------------------- */ tdstFileType *fn_Tree_p_stIsAFileType( char *_szFileType ) { long lFileType; tdstFileType *p_stFT = g_d_stFileType; for (lFileType = 0; lFileType < g_lNumberOfFileTypes; lFileType++, p_stFT++ ) { if (stricmp( p_stFT->szExt, _szFileType) == 0) return p_stFT; } return NULL; } /* ---------------------------------------------------------------------------------------- Description : add a file type in list ---------------------------------------------------------------------------------------- */ tdstFileType *fn_Tree_p_stAddFileType( char *_szFileType ) { tdstFileType *p_stFT; char *p_szExt; if ( (p_stFT = fn_Tree_p_stIsAFileType( _szFileType )) != NULL) return p_stFT; if (g_lNumberOfFileTypes == g_lNumberMaxOfFileTypes ) { g_lNumberMaxOfFileTypes += 50; if (g_lNumberMaxOfFileTypes == 50) { g_d_stFileType = (tdstFileType *) malloc (g_lNumberMaxOfFileTypes * sizeof( tdstFileType ) ); } else { g_d_stFileType = (tdstFileType *) realloc( g_d_stFileType, g_lNumberMaxOfFileTypes * sizeof( tdstFileType ) ); } } p_stFT = &g_d_stFileType[ g_lNumberOfFileTypes++ ]; p_szExt = p_stFT->szExt; while (*_szFileType != 0) *p_szExt++ = tolower( *_szFileType++ ); *p_szExt = 0; p_stFT->lUsed = 0; p_stFT->bConsider = fn_IniD_bGetFileTypeConsiderStatus( p_stFT->szExt ); return p_stFT; } /* ---------------------------------------------------------------------------------------- Description : add the type of given file in list and increase used count of file type ---------------------------------------------------------------------------------------- */ void fn_Tree_vAddFileTypeFromFile( char *_szFile ) { char *szExt; tdstFileType *p_stFT; if ( (szExt = strrchr(_szFile, '.')) == NULL) szExt = _szFile + strlen( _szFile ); else szExt++; p_stFT = fn_Tree_p_stAddFileType( szExt ); p_stFT->lUsed++; } /* ---------------------------------------------------------------------------------------- Description : get file type of a given file _szFileName -> file name Returns (tdstFileType ) file type ---------------------------------------------------------------------------------------- */ tdstFileType *fn_Tree_p_stGetFileFileType( char *_szFileName ) { char *szExt; if ( (szExt = strrchr(_szFileName, '.')) == NULL) szExt = _szFileName + strlen( _szFileName ); else szExt++; return fn_Tree_p_stIsAFileType( szExt ); } /* ---------------------------------------------------------------------------------------- Description : return bConsider flag of extension of given file _szFile -> file name Returns (BOOL ) bConsider flag of extension ---------------------------------------------------------------------------------------- */ BOOL fn_Tree_bConsiderFile( char *_szFile ) { tdstFileType *p_stFT; p_stFT = fn_Tree_p_stGetFileFileType( _szFile ); if (p_stFT == NULL) return FALSE; return p_stFT->bConsider; } /* ======================================================================================= TREE FUNCTIONS ======================================================================================= */ /* --------------------------------------------------------------------------------------- fill a tdstProject structure with name and describing an empty project --------------------------------------------------------------------------------------- */ void fn_Tree_vInitProject( tdstProject *_p_stProj, char *_szName ) { _p_stProj->szName = (char *) malloc( strlen(_szName) + 1 ); strcpy( _p_stProj->szName, _szName ); _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; _p_stProj->lNumberOfSubProjects = 0; _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfFiles = 0; _p_stProj->d_stFile = NULL; } /* --------------------------------------------------------------------------------------- fill a tdstProject structure with pointer name and describing an empty project --------------------------------------------------------------------------------------- */ void fn_Tree_vInitProjectWithPointerName( tdstProject *_p_stProj, char *_szName ) { _p_stProj->szName = _szName; _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; _p_stProj->lNumberOfSubProjects = 0; _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfFiles = 0; _p_stProj->d_stFile = NULL; } /* --------------------------------------------------------------------------------------- fill a tdstFile structure with name --------------------------------------------------------------------------------------- */ void fn_Tree_vInitFile( tdstFile *_p_stFile, char *_szName ) { _p_stFile->szName = (char *) malloc( strlen(_szName) + 1 ); strcpy( _p_stFile->szName, _szName ); _p_stFile->bGet = FALSE; } /* --------------------------------------------------------------------------------------- fill a tdstFile structure with pointer name --------------------------------------------------------------------------------------- */ void fn_Tree_vInitFileWithPointerName( tdstFile *_p_stFile, char *_szName ) { _p_stFile->szName = _szName; _p_stFile->bGet = FALSE; } /* --------------------------------------------------------------------------------------- retrieve a subproject --------------------------------------------------------------------------------------- */ tdstProject *fn_Tree_p_stGetProject( tdstProject *_p_stInProj, char *_szName ) { char *p_cCur; char *p_cNext; tdstProject *p_stCurProj; long lSubProj; if (_p_stInProj == NULL) return NULL; p_cCur = _szName; while (1) { p_cCur = strchr( p_cCur, '/' ); if (p_cCur == NULL) break; *p_cCur = '\\'; } if ( strnicmp( _szName, _p_stInProj->szName, strlen( _p_stInProj->szName )) != 0) return NULL; p_cCur = _szName + strlen( _p_stInProj->szName ); p_stCurProj = _p_stInProj; while (*p_cCur != 0) { p_cCur ++; p_cNext = strchr(p_cCur, '\\'); if (p_cNext != NULL) *p_cNext = 0; for (lSubProj = 0; lSubProj < p_stCurProj->lNumberOfSubProjects; lSubProj++) { if (stricmp( p_stCurProj->d_stSubProject[lSubProj].szName, p_cCur) == 0) break; } if (lSubProj == p_stCurProj->lNumberOfSubProjects) return NULL; p_stCurProj = &p_stCurProj->d_stSubProject[lSubProj]; p_cCur += strlen( p_cCur ); if (p_cNext != NULL) *p_cNext = '\\'; } return p_stCurProj; } /* --------------------------------------------------------------------------------------- retrieve a file with name --------------------------------------------------------------------------------------- */ tdstFile *fn_Tree_p_stGetFile( tdstProject *_p_stInProj, char *_szName ) { tdstProject *p_stProj; tdstFile *p_stFile; char *p_szShortName; long lFile = 0; p_szShortName = strrchr( _szName, '\\' ); *p_szShortName++ = 0; p_stProj = fn_Tree_p_stGetProject( _p_stInProj, _szName ); *(p_szShortName - 1) = '\\'; if ( p_stProj == NULL) return NULL; for ( p_stFile = p_stProj->d_stFile; lFile < p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { if (stricmp( p_szShortName, p_stFile->szName) == 0) return p_stFile; } return NULL; } /* --------------------------------------------------------------------------------------- free a project information --------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProject( tdstProject *_p_stProj, BOOL _bDelete ) { long lIndex; /* free files */ if (_p_stProj == NULL) return; if (_p_stProj->d_stFile) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++) free ( _p_stProj->d_stFile[lIndex].szName ); free (_p_stProj->d_stFile ); _p_stProj->d_stFile = NULL; _p_stProj->lNumberOfFiles = 0; } /* free sub project */ if (_p_stProj->d_stSubProject ) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfSubProjects; lIndex ++) fn_Tree_vFreeProject( &_p_stProj->d_stSubProject[lIndex], TRUE ); free (_p_stProj->d_stSubProject ); _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfSubProjects = 0; } /* free project */ if (_bDelete) free ( _p_stProj->szName ); } /* --------------------------------------------------------------------------------------- free a project information tree --------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProjectTree( tdstProject *_p_stProj, BOOL _bDelete ) { fn_Tree_vFreeProject( _p_stProj, _bDelete ); if (_bDelete) { free ( _p_stProj ); _p_stProj = NULL; } } /* ---------------------------------------------------------------------------------------- Description : free list of file in a vss project structure ---------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProjectFileList( tdstProject *_p_stProj ) { long lIndex; if (_p_stProj->d_stFile) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++) free ( _p_stProj->d_stFile[lIndex].szName ); free (_p_stProj->d_stFile ); _p_stProj->d_stFile = NULL; _p_stProj->lNumberOfFiles = 0; } } /* --------------------------------------------------------------------------------------- set all vss project to not obtain --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNothing( tdstProject *_p_stProj) { long lSubProj; long lFile = 0; tdstFile *p_stFile = _p_stProj->d_stFile; /* * dont obtain current project */ _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; /* * dont obtain files */ for (; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { p_stFile->bGet = FALSE; } /* * dont obtain sub project */ for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) fn_Tree_vGetNothing( &_p_stProj->d_stSubProject[lSubProj] ); } /* --------------------------------------------------------------------------------------- refresh obtaining state for vss tree --------------------------------------------------------------------------------------- */ void fn_Tree_vRefreshWithFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList ) { int iFile; char *szFileName; tdstProject *p_stSubProj; tdstFile *p_stFile; BOOL bRecurse; BOOL bFile; fn_Tree_vGetNothing( _p_stProj ); for (iFile = 0; iFile < _p_stFileList->lNumberOfFiles; iFile ++) { szFileName = _p_stFileList->d_szFile[iFile]; if (*szFileName == '-') { switch( *(szFileName + 1) ) { case 'R': bRecurse = TRUE; bFile = FALSE; break; case 'P': bRecurse = FALSE; bFile = FALSE; break; default: bRecurse = FALSE; bFile = FALSE; } szFileName += 3; } else { bRecurse = FALSE; bFile = TRUE; } if (bFile) { if ( (p_stFile = fn_Tree_p_stGetFile( _p_stProj, szFileName ) ) != NULL) p_stFile->bGet = TRUE; } else { if ( (p_stSubProj = fn_Tree_p_stGetProject( _p_stProj, szFileName ) ) != NULL) { p_stSubProj->bGet = TRUE; p_stSubProj->bRecurse = bRecurse; } } } } /* --------------------------------------------------------------------------------------- count recursively number of file to get all folder name the user want to obtain --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNumberOfFilesOrProjectsToGet( tdstProject *_p_stProj, long *_p_lNbFiles ) { long lSubProj; long lFile; tdstFile *p_stFile; if (_p_stProj->bGet) { (*_p_lNbFiles)++; if (_p_stProj->bRecurse) return; } else { for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ ) if (p_stFile->bGet) (*_p_lNbFiles) ++; } for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) fn_Tree_vGetNumberOfFilesOrProjectsToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles ); } /* --------------------------------------------------------------------------------------- write recursively file to obtain in given array of string --------------------------------------------------------------------------------------- */ void fn_Tree_vGetFilesOrProjectToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile ) { long lSubProj; long lFile; tdstFile *p_stFile; if (_p_stProj->bGet) { strcpy ( _d_szFile[ *_p_lNbFiles ], (_p_stProj->bRecurse)?"-R ":"-P"); strcat( _d_szFile[ (*_p_lNbFiles)++ ], g_szFullName ); if (_p_stProj->bRecurse) return; } else { for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ ) if (p_stFile->bGet) sprintf(_d_szFile[ (*_p_lNbFiles)++ ], "%s\\%s", g_szFullName, p_stFile->szName ); } for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) { strcat( g_szFullName, "\\"); strcat( g_szFullName, _p_stProj->d_stSubProject[lSubProj].szName ); fn_Tree_vGetFilesOrProjectToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles, _d_szFile ); *strrchr( g_szFullName, '\\' ) = 0; } } /* --------------------------------------------------------------------------------------- count recursively all files to obtain (not project) --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNumberOfFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, BOOL _bAll ) { long lFile = 0; tdstProject *p_stSubProj = _p_stProj->d_stSubProject; tdstFile *p_stFile = _p_stProj->d_stFile; /* * add number of obtained file in current project */ if (_p_stProj->bGet || _bAll) (*_p_lNbFiles) += _p_stProj->lNumberOfFiles; else { for ( ; lFile < _p_stProj->lNumberOfFiles; p_stFile++, lFile++ ) if (p_stFile->bGet) (*_p_lNbFiles)++; } /* * call recursively function for each sub project */ for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile++, p_stSubProj++) { fn_Tree_vGetNumberOfFilesToGet( p_stSubProj, _p_lNbFiles, (_p_stProj->bRecurse) || _bAll ); } } /* --------------------------------------------------------------------------------------- write recursively file to obtain (no project) in given array of string --------------------------------------------------------------------------------------- */ void fn_Tree_vGetFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile, BOOL _bAll ) { long lFile = 0; tdstProject *p_stSubProj = _p_stProj->d_stSubProject; tdstFile *p_stFile = _p_stProj->d_stFile; for ( ; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { if ( _bAll || (_p_stProj->bGet) || (p_stFile->bGet) ) sprintf( _d_szFile[ (*_p_lNbFiles)++ ], "%s\\%s", g_szFullName, p_stFile->szName ); } for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile ++, p_stSubProj++) { strcat( g_szFullName, "\\"); strcat( g_szFullName, p_stSubProj->szName ); fn_Tree_vGetFilesToGet( p_stSubProj, _p_lNbFiles, _d_szFile, _bAll || _p_stProj->bRecurse ); *strrchr( g_szFullName, '\\' ) = 0; } } /* ---------------------------------------------------------------------------------------- Description : build list of files to get _p_stProj -> project to look in **_ppp_szFile -> pointer on a list that will be filled Returns (long ) number of files in list ---------------------------------------------------------------------------------------- */ long fn_Tree_lBuildListOfFilesToGet( tdstProject *_p_stProj, char ***_ppp_szFile ) { long lNbFiles, lFile; lNbFiles = 0; fn_Tree_vGetNumberOfFilesToGet( _p_stProj, &lNbFiles, FALSE ); if (lNbFiles == 0) return 0; *_ppp_szFile = (char **) malloc (lNbFiles * sizeof ( char *) ); for (lFile = 0; lFile < lNbFiles; lFile ++) (*_ppp_szFile)[lFile] = (char *) malloc ( MAX_PATH ); strcpy (g_szFullName, _p_stProj->szName ); lNbFiles = 0; fn_Tree_vGetFilesToGet( _p_stProj, &lNbFiles, *_ppp_szFile, FALSE ); return lNbFiles; } /* ---------------------------------------------------------------------------------------- Description : free a list of files previously build with fn_TREE_lBuildListOfFilesToGet function _lNumberOfFiles -> number of files in list *_pp_szFile -> list of file ---------------------------------------------------------------------------------------- */ void fn_Tree_vFreeListOfFilesToGet( long _lNumberOfFiles, char **_pp_szFile ) { long lFile; if (_lNumberOfFiles == 0) return; for (lFile = 0; lFile < _lNumberOfFiles; lFile ++) free( _pp_szFile[lFile] ); free( _pp_szFile ); } /* --------------------------------------------------------------------------------------- dump a list in a file --------------------------------------------------------------------------------------- */ void fn_TREE_vDumpListInFile( char *szTitle, long lNbFiles, char **d_szFileName ) { FILE *hpFile; long lFile; CTime oTime = GetCurrentTime(); hpFile = fopen( "filelst.txt", "at" ); if (hpFile == NULL) return; fprintf( hpFile, "*********** %s (%d files) **************\n", (char*)(LPCTSTR) (oTime.Format( "%d/%m/%y %H:%M:%S" )), lNbFiles ); fprintf( hpFile, "%s\n\n", szTitle ); for ( lFile = 0; lFile < lNbFiles; lFile ++) { fprintf( hpFile, "%s\n", d_szFileName[ lFile ] ); } fclose( hpFile ); } /* --------------------------------------------------------------------------------------- set new list of file from analysis of vss tree obtaining state --------------------------------------------------------------------------------------- */ BOOL fn_TREE_bGetFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList, char _cConfig, char *_szFileListName ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ char szFileListId[20]; long lNbFiles; char **d_szFile; long lFile; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ sprintf(szFileListId, "FileList-Config%02d", _cConfig); lNbFiles = 0; fn_Tree_vGetNumberOfFilesOrProjectsToGet( _p_stProj, &lNbFiles ); if (lNbFiles == 0) return FALSE; d_szFile = (char **) malloc (lNbFiles * sizeof ( char *) ); for (lFile = 0; lFile < lNbFiles; lFile ++) d_szFile[lFile] = (char *) malloc ( MAX_PATH ); strcpy (g_szFullName, _p_stProj->szName ); lNbFiles = 0; fn_Tree_vGetFilesOrProjectToGet( _p_stProj, &lNbFiles, d_szFile ); fn_IniD_vFreeFileList( _p_stFileList ); strcpy( _p_stFileList->szId, szFileListId ); strcpy( _p_stFileList->szName, _szFileListName ); _p_stFileList->lNumberOfFiles = lNbFiles; _p_stFileList->d_szFile = d_szFile; //fn_vUpdateFilesToObtainList(); return TRUE; } /* ======================================================================================= Function for local tree ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : fill project with local content _p_stProject -> project to fill _szEndName -> end of current path which is a global var ) ---------------------------------------------------------------------------------------- */ void fn_Tree_vFillProjectFromDisk( tdstProject *_p_stProject, char *_szEndName ) { long lNbFiles = 0; long lNbProjs = 0; tdstProject *p_stSubProj; WIN32_FIND_DATA stFindData; HANDLE hFind; if (g_hProjectWindow != NULL) SetWindowText( g_hProjectWindow, _p_stProject->szName ); strcpy( _szEndName, "*.*" ); hFind = FindFirstFile(g_szFullName, &stFindData ); *_szEndName = 0; if( hFind != INVALID_HANDLE_VALUE) { do { if ( stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if ( *stFindData.cFileName != '.') { gs_d_szProj[ lNbProjs ] = (char *) malloc( strlen(stFindData.cFileName) + 1 ); strcpy ( gs_d_szProj[ lNbProjs ], stFindData.cFileName ); lNbProjs++; } } else { gs_d_szFile[ lNbFiles ] = (char *) malloc( strlen(stFindData.cFileName) + 1 ); strcpy ( gs_d_szFile[ lNbFiles ], stFindData.cFileName ); lNbFiles++; } } while(FindNextFile( hFind, &stFindData )); FindClose( hFind ); } /* * allocate memory for all files and all sub projects */ if (lNbProjs) { _p_stProject->lNumberOfSubProjects = lNbProjs; _p_stProject->d_stSubProject = (tdstProject *) malloc ( lNbProjs * sizeof( tdstProject) ); for (lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++) fn_Tree_vInitProjectWithPointerName( &_p_stProject->d_stSubProject[ lNbProjs ], gs_d_szProj[lNbProjs] ); } if ( lNbFiles ) { if (lNbFiles > 2048) AfxMessageBox( "more than 2048 files in a folder\r\nthere will soon be a big bug !!!\r\nContact me .\r\n", MB_ICONSTOP | MB_OK); _p_stProject->lNumberOfFiles = lNbFiles; _p_stProject->d_stFile = (tdstFile *) malloc ( lNbFiles * sizeof( tdstFile) ); for (lNbFiles = 0; lNbFiles < _p_stProject->lNumberOfFiles; lNbFiles ++) { fn_Tree_vInitFileWithPointerName( &_p_stProject->d_stFile[ lNbFiles ], gs_d_szFile[ lNbFiles ] ); fn_Tree_vAddFileTypeFromFile( gs_d_szFile[ lNbFiles ] ); } } /* * construct sub project tree */ for (p_stSubProj = _p_stProject->d_stSubProject, lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++, p_stSubProj++) { lNbFiles = sprintf( _szEndName, "%s\\", p_stSubProj->szName ); fn_Tree_vFillProjectFromDisk( p_stSubProj, _szEndName + lNbFiles ); *_szEndName = 0; } } /* ---------------------------------------------------------------------------------------- Description : build local tree _p_stRootProject -> project to fill (correspond to root project) _szRootName -> project name (root) Returns (BOOL ) TRUE if tree has been build, otherwise FALSE ---------------------------------------------------------------------------------------- */ BOOL fn_Tree_bBuildFromDisk( tdstProject **_pp_stRootProject, char *_szRootName, HWND _hProjectWindow ) { /* * check existance of root project */ if (_access( _szRootName, 0) != 0 ) return FALSE; if (*_pp_stRootProject != NULL) fn_Tree_vFreeProjectTree(*_pp_stRootProject, TRUE ); fn_Tree_vFreeFileTypeList(); g_hProjectWindow = _hProjectWindow; /* * create and initialize root project */ *_pp_stRootProject = (tdstProject *) malloc( sizeof (tdstProject) ); fn_Tree_vInitProject( *_pp_stRootProject, _szRootName ); // allocate memory for name storage gs_d_szFile = (char **) malloc ( 2048 * sizeof( char *) ); gs_d_szProj = (char **) malloc ( 2048 * sizeof( char *) ); // get recursively and from root project vss tree sprintf( g_szFullName, "%s\\", _szRootName ); fn_Tree_vFillProjectFromDisk( *_pp_stRootProject, g_szFullName + strlen( g_szFullName) ); free( gs_d_szFile ); free( gs_d_szProj ); return TRUE; }