//.. 文件操作
import win.ole;
namespace fsys;
   
::Shell32 := ..raw.loadDll("Shell32")
 
SetCurrentDirectory := ::Kernel32.api( "SetCurrentDirectory", "int(string path )"); 
GetCurrentDirectory := ::Kernel32.api( "GetCurrentDirectory", "INT(INT nBufferLength, str & lpBuffer )"); 
GetSystemDirectory := ::Kernel32.api( "GetSystemDirectoryA", "int(str &str,int size )"); 
GetWindowsDirectory := ::Kernel32.api( "GetWindowsDirectoryA", "int(str &str,int size )");
GetTempPath := ::Kernel32.api( "GetTempPathA", "int(int size ,str &str)");  
FindFirstFile := ::Kernel32.api("FindFirstFileA", "int(string,struct&)") 
FindNextFile := ::Kernel32.api("FindNextFileA", "int(int,struct&)") 
FindClose := ::Kernel32.api("FindClose", "int(int)") 
GetShortPathName = ::Kernel32.api("GetShortPathName","int(string long,str&short,int size)")
GetLongPathName = ::Kernel32.api("GetLongPathName","int(string  short,str&long,int size)")

longpath = function(path){
	var len,path = GetLongPathName(path,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
	if(len) return path
}

shortpath = function(path){
	if(!path)
		error("fsys.shortpath()参数不能为空",2)
	if(!..string.indexAny(path,"/\"))
		return path;
	var len,path = GetShortPathName( ..io.fullpath(path) ,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
	return len ? path;
}

joinpath = function(dir,path,...){  

	if(! (dir && path) ){
		error("路径参数不能为空",2)
	}
	dir = ..string.replace(dir,'/','\\');
	path = ..string.replace(path,'/','\\');
	var spath =  path[1]=='\\'#
	if( dir[#dir]=='\\'#  ){
		if( spath ) path = ..string.right(path,-2);
		path = dir + path;
	}
	elseif(spath){
		path = dir + path;
	}
	else{
		path = dir +'\\'+ path;	
	}
	
	if(!...)return path;
	return joinpath(path,...);
}
 
getCurDir = function(){
	var re,str = GetCurrentDirectory(0x104,0x104) //_MAX_PATH = 0x104
	return str;
}

setCurDir = function(dir){ 
	return SetCurrentDirectory( ..io.fullpath(dir) );
}

getSysDir = function(){
	var re,str = GetSystemDirectory(0x104,0x104) //_MAX_PATH = 0x104
	return str;
}

getWinDir = function(){
	var re,str = GetWindowsDirectory(0x104,0x104)
	return str;
}

getTempDir = function(){
	var re,str = GetTempPath(0x104,0x104)
	return str;
}

var CreateDirectoryApi = ::Kernel32.api("CreateDirectoryA", "bool(string lpPathName,pointer lpSecurityAttributes)");
var createDirAux;
createDirAux = function(strDir){ 
	if(..io.exist(strDir))
		return true; 
		
	var nFound = ..string.lastIndexAny( strDir,"/\" );
	if(nFound &&  strDir[nFound-1]!=':'#){ 
		if(! createDirAux( ..string.left(strDir,nFound - 1) ) )
			return false;
	}

	return CreateDirectoryApi(strDir); 
}
createDir = function(strDir){
	strDir = ..string.trimright(strDir,"/\");
	strDir = ..io.fullpath(strDir)
	if( createDirAux( strDir ) )
		return strDir; 
}

getExtensionName = function(path){
	var p = ..string.lastIndexAny(path,".");
	if(p)
		return ..string.lower( ..string.right( path,-(p+1) ) );
}
 
getParentDir = function(path){
	path = ..string.trimright(path,"/\" );
	var f = ..string.lastIndexAny( path,"/\" );
	return f ? ..string.left(path,f  ) 
}

createParentDir = function(strDir){
	createDir( getParentDir(strDir) );
}

searchFile = function(filename,...){
	if( ... ){ 
		var dir = {...}
		var path;
		for(i=1;#dir ){
			path = joinpath(dir[i],filename)
			if( ..io.exist(path ) )
				return path;
		} 
	} 
	else{
	
		return searchFile( filename, ..io.localpath("\"))
			|| searchFile( filename, ..io._exedir )
			|| searchFile( filename,getCurDir() ) 
			|| searchFile( filename,getSysDir() ) 
			|| searchFile( filename,getWinDir() )  
	}
}

/**intellisense(fsys) 
shortpath(__/*路径*/) = 转换为短文件名
longpath(__/*路径*/) = 转换为长文件名
joinpath("__/*父目录*/",不定个数子路径) = 拼接多个文件路径\n子路径参数可以是一个或多个\n此函数自动处理首尾斜杠拼接,转换为合法格式
getCurDir() = 获取当前目录
setCurDir(__/*目录*/) = 设置当前目录
getSysDir() = 返回系统目录
getWinDir() = 返回windows目录
getTempDir() = 返回临时目录
createDir("__") = 创建目录路径.\n返回创建成功的完整文件路径
createParentDir("__") = 创建指定路径的父目录.
getExtensionName("__") = 返回文件后缀名,转换为小写.\n无后缀名则返回null空值
getParentDir("__") = 返回指定路径的父目录
searchFile("__/*文件名*/") = 检查程序根目录、当前工作目录、系统目录\n如果包含指定文件,则返回文件完整路径
searchFile("__/*文件名*/",目录) = 检查指定目录下是否包含指定文件\n如果存在返回完整路径,否则返回null
end intellisense**/

SHGetSpecialFolderLocation = Shell32.api("SHGetSpecialFolderLocation","int(int hwndOwner, int nFolder,pointer &ppidl)" )
SHFileOperation = Shell32.api("SHFileOperationA","int(pointer lpFileOp)"); 
SHGetPathFromIDList = Shell32.api("SHGetPathFromIDListA","bool(POINTER pidl,str & str)");  
ILCreateFromPath = Shell32.api("ILCreateFromPath","pointer(string path)");  
idListFromPath = function(path){
	return ILCreateFromPath( ..string.toUnicode( ..io.fullpath(path) ) )
}
pathFromIdList = function(pIdl,free){ 
	if(!pIdl)return;
	var ok,path = SHGetPathFromIDList(pIdl,0x104/*_MAX_PATH*/)
	if(free)::CoTaskMemFree(pIdl)
	if(ok)return path;
} 
getSpecial = function(id=0,toPath=true){
	var re,pIdl = SHGetSpecialFolderLocation (0,id); 
	if(re>=0){ 
		if(toPath) return pathFromIdList(pIdl,true); 
		return pIdl;
	}
} 

var SHFILEOPSTRUCT = class {
	int hwnd = 0;
	INT wFunc;
	string pFrom;
	string pTo;
	WORD fFlags;
	int fAnyOperationsAborted;
	pointer hNameMappings;
	string lpszProgressTitle;//进度条标题，仅在fFlags标志中指定了//FOF_SIMPLEPROGRESS
}

var getOpFiles = function(path,flag){
	if(type(path)==type.table){
    	for(k,v in path){
    		path[k] = ..string.trimright(..io.fullpath(v),"\/")
    	} 
    	..table.push(path,'\0');
    	path = ..string.join(path,'\0');
    	flag = flag | 0x1/*_FOF_MULTIDESTFILES*/
    }
    else {
    	path = ..io.fullpath(path) 
    	path = ..string.trimright(path,"\/") + '\0'; 
    }
    return path,flag;	
}

operation = function( op, 
	from,to,
	flag = 0x10/*_FOF_NOCONFIRMATION*/ | 0x4/*_FOF_SILENT*/ | 0x200/*_FOF_NOCONFIRMMKDIR*/,
	title,hwnd ) { 
	
    var fo = SHFILEOPSTRUCT(); 
    if( ! (#from)  ) error("请指定源文件路径",3); 
    from = getOpFiles(from,0); //MSDN:This string must be double-null terminated. 
    if(#to){
    	to,flag = getOpFiles(to,flag);
    } 
    fo.wFunc = op;
    fo.pFrom = from ;
    fo.pTo = to; 
    fo.fFlags = flag;
    fo.hwnd = hwnd; 
	if(title){
    	fo.lpszProgressTitle = title + '\0\0';
    	flag |= 0x100/*_FOF_SIMPLEPROGRESS*/
    	
    }
    
    fo = ..raw.malloc(fo)
    for(i=21;#fo;1){
    	fo[i-2] = fo[i] 
    } 
    
    return SHFileOperation(fo) == 0; 
} 
delete = function(from,flag,title,hwnd){
	return operation( 0x3,from, ,flag,title,hwnd); 
}
move = function(from,to,flag,hwnd){ 
	return operation( 0x1/*_FO_MOVE*/,from,to,flag,title,hwnd); 
}
copy = function(from,to,flag,title,hwnd){ 
	return operation( 0x2/*_FO_COPY*/,from,to,flag,title,hwnd); 
}
rename = function(from,to,flag,title,hwnd){ 
	return operation( 0x4/*_FO_RENAME*/,from,to,flag,title,hwnd); 
}

/**intellisense(fsys)
idListFromPath(__/*路径*/) = 路径转换为名称ID(PIDL)\路径必须存在
pathFromIdList(.(PIDL名称ID,是否释放PIDL) = 名称ID(PIDL)转换为路径
getSpecial(_CSIDL__) = 获取指定目录，参数为_CSIDL开头的常量\nfsys.getSpecial()//默认获取桌面目录\nfsys.getSpecial( _CSIDL_RECENT ) //获取用户最近文档目录\n可选指定第二个参数为false,以返回原始PIDL句柄
delete("__/*路径*/") = 删除文件或目录，路径参数可以是多个路径组成的数组\n支持非空目录,文件名支持通配符\n可选增加一个参数,使用_FOF__前缀常量指定附加选项 
move(.(源路径,目标路径) = 移动文件或目录，路径参数可以是多个路径组成的数组\n文件名支持通配符\n可选增加一个参数,使用_FOF__前缀常量指定附加选项
copy(.(源路径,目标路径) = 复制文件或目录，路径参数可以是多个路径组成的数组\n文件名支持通配符\n可选增加一个参数,使用_FOF__前缀常量指定附加选项
rename(.(源路径,目标路径) = 重命名文件或目录，路径参数可以是多个路径组成的数组 \n可选增加一个参数,使用_FOF__前缀常量指定附加选项
end intellisense**/
 
/*intellisense(fsys)*/ 
WIN32_FIND_DATA := class{
    INT dwFileAttributes;
    struct ftCreationTime = ::FILETIME();
    struct ftLastAccessTime = ::FILETIME();
    struct ftLastWriteTime = ::FILETIME();
    INT nFileSizeHigh ;
    INT nFileSizeLow; 
    INT dwReserved0;
    INT dwReserved1;
    BYTE cFileName[ 260 ];
    BYTE cAlternateFileName[ 14 ];
}
/*end intellisense*/

/**intellisense(findData)
dwFileAttributes = 0;//文件属性
ftCreationTime = 文件创建时间\n请调用fsys.fromFileTime()转换为time对象
ftLastAccessTime = 文件最后一次访问时间\n请调用fsys.fromFileTime()转换为time对象
ftLastWriteTime =  文件最后一次修改时间\n请调用fsys.fromFileTime()转换为time对象 
nFileSizeHigh = 文件长度高32位 
nFileSizeLow = 件长度低32位 
cFileName = 长文件名\n请调用string.str去掉尾部的\0
cAlternateFileName = 8.3格式文件名\n请调用string.str去掉尾部的\0
end intellisense**/

FileTimeToSystemTime = ::Kernel32.api("FileTimeToSystemTime","int(struct filetime,struct& time)")
fromFileTime = function(filetime){
	var ok,tm = FileTimeToSystemTime(filetime,..time() )
	if(ok)
		return tm;
} 


/**intellisense()
?fsys.WIN32_FIND_DATA = findData.
?.fromFileTime = !time. 
fsys.fromFileTime(__/*FILETIME结构体*/) = 将::FILETIME结构体转换为time对象
end intellisense**/

var function  enum_aux(dir,p="*.*",proc ,enumSubdir){
	if( not ..string.endWith( dir,"\") ) {
		dir = dir + "\";
	}
	
	var matchDir = ( type(enumSubdir)==type.function );
	var data = WIN32_FIND_DATA()
	var filename;
	var fullpath;
	var hf,data =  FindFirstFile(dir + p,data); //搜索文件，按指定的通配符
	if(hf != -1/*_INVALID_HANDLE_NUM*/){
		do{ 
			filename =..string.str( data.cFileName ) 
			if( (#filename) && (filename!=".") &&  ( filename!=".." ) ){
				fullpath =  joinpath(dir,filename)
				if( ( data.dwFileAttributes & 0x10/*_FILE_ATTRIBUTE_DIRECTORY*/ ) == 0 ){  
					if( proc( dir,filename,fullpath,data ) === false ) 
						return false; 
				}
				else {
					if( (filename!=".") &&  ( filename!=".." ) ) {
						if(  proc( filename,,fullpath,data) === false )  
							return false; 
					}
				}
			}
			
		} while( FindNextFile(hf,data) )
		FindClose(hf);
	} 
	
	var hf,data =  FindFirstFile(dir + "*.*",data); //搜索所有目录
	if(hf != -1/*_INVALID_HANDLE_NUM*/){
		do{
			if( data.dwFileAttributes & 0x10/*_FILE_ATTRIBUTE_DIRECTORY*/ ) { 
				filename =..string.str( data.cFileName )  
				if( (filename!=".") &&  ( filename!=".." ) ) {
					if(enumSubdir){ 
						fullpath = joinpath(dir,filename);
						if( (enumSubdir===true) || enumSubdir( fullpath,filename )!==false  ) 
							if( enum_aux( fullpath,p,proc,enumSubdir ) === false )
								return false;
					}
				}
			}
		}while(FindNextFile(hf,data) )
		FindClose(hf);
	}
}

function enum(dir,p="*.*",proc,enumSubdir=true/*是否搜索子目录*/){ 
	dir = ..io.fullpath(dir);  
	assert(..io.exist(dir) ,"目录不存在" + (dir:"") )
	assert(type(proc)==type.function,"必须为win.enumFiles指定回调函数")  
	return enum_aux( dir,p,proc,enumSubdir);
}

/**intellisense(fsys)
enum(目录路径,掩码,回调函数,是否处理子目录)  =  @.enum( "/遍历目录路径", "*.*",\n	function(dir,file,fullpath,findData){ \n		if(file){ \n           	io.print("发现文件："+file,"完整路径："+fullpath)__\n		}\n		else{\n			io.print( "发现目录：" + dir )\n		}\n	} \n	,/*\n	如果此参数为false则忽略子目录,\n	如果是函数,则每次开始遍历一个子目录前使用其完整路径数参数,调用该函数,返回值为false忽略该目录\n	*/\n);
end intellisense**/

getAttributes = ::Kernel32.api("GetFileAttributesA","int(str path)")
setAttributes = ::Kernel32.api("SetFileAttributesA","int(str path,int attributes)")
attrib  = function(f,remove,add){
	f = ..io.fullpath(f)
	
	var a = getAttributes(f);
	if(!remove && ! add)
		return a;
		
	remove := 0;
	add := 0;
	a = ( a  & ~remove ) | add ; 
	if( setAttributes( f,a) )
		return a;
}
 
isHidden = function(f){ 
	var s = attrib(f)
	return (s!=-1) && ( s & 2/*_FILE_ATTRIBUTE_HIDDEN*/);
}
isSystem = function(f){
	var s = attrib(f)
	return (s!=-1) && ( s & 4/*_FILE_ATTRIBUTE_SYSTEM*/);
}
isDir = function(f){
	var s = attrib(f)
	return (s!=-1) && ( s & 0x10/*_FILE_ATTRIBUTE_DIRECTORY*/);
}
isReadonly = function(f){
	var s = attrib(f)
	return (s!=-1) && ( s & 1/*_FILE_ATTRIBUTE_READONLY*/);
}


/**intellisense(fsys)
setAttributes("",_FILE_ATTRIBUTE__) = 设置文件属性
attrib("__/*文件路径*/") = 返回文件属性\n以_FILE_ATTRIBUTE_前缀的常量标志各属性
attrib("",_FILE_ATTRIBUTE__/*多个属性用 | 链接*/) = 移除件属性\n参数一为文件路径\n参数二可以用 | 操作符连接多个属性\n成功返回新属性,失败返回null
attrib("",/*移除*/,_FILE_ATTRIBUTE__/*多个属性用 | 链接*/) = 添加文件属性\n参数一为文件路径\n参数三可以用 | 操作符连接多个属性\n成功返回新属性,失败返回null
isDir("__/*路径*/")  = 路径是否目录\n调用attrib检查目标路径是否具有_FILE_ATTRIBUTE_DIRECTORY属性
isReadonly("__/*文件路径*/")  = 文件是否只读\n调用attrib检查文件是否具有_FILE_ATTRIBUTE_READONLY属性
isSystem("__/*文件路径*/")  = 是否系统文件\n调用attrib检查文件是否具有_FILE_ATTRIBUTE_SYSTEM属性
isHidden("__/*文件路径*/")  = 是否隐藏文件\n调用attrib检查文件是否具有_FILE_ATTRIBUTE_HIDDEN属性 
end intellisense**/

::Shlwapi := ..raw.loadDll("Shlwapi.dll");
StrFormatByteSize = Shlwapi.api("StrFormatByteSize64A", "string(INT low,INT high, str&, INT)" )
formatSize = function (lSize=0,hSize=0){ 
	var re, size = StrFormatByteSize(lSize,hSize, 128, 128);
	return size;
}
namespace path{ 
	PathCompactPath = Shlwapi.api("PathCompactPathA", "int(pointer hdc, str&lpszPath, INT dx)" )
	PathCanonicalize = Shlwapi.api("PathCanonicalizeA", "int(str &dst,str src)" )  
	PathCommonPrefix = Shlwapi.api("PathCommonPrefixA", "int(str,str,str&)" ) 
	
	compact = function(path,pix = 300){
		var re,path = PathCompactPath( ,path,pix)
		return path;
	} 
	commonPrefix = function(path,path2){
		var l,p = PathCommonPrefix(canonicalize(path),canonicalize(path2),0x104/*_MAX_PATH*/)
		if(l) return addBackslash(p);//保证尾部为斜杠
	} 
	cmp = function(path,path2){
		return ..string.cmp(canonicalize(path),canonicalize(path2));
	} 
 	canonicalize = function(path){
 		var ret,cp = PathCanonicalize(0x104/*_MAX_PATH*/,..io.fullpath(path) );
 		if(ret)return ..string.trimright( cp,"\");//保证尾部不为斜杠
 	}
 	addBackslash = function(path){
 		return ( path[#path] =='\\'# )?path:path+"\"
 	}  
 	relative = function(path,dir,prefix=true){
 		path = canonicalize(path) 
 		dir = canonicalize(dir) 
 		var common = commonPrefix(path,dir);  
 		if( #common && ( 0 == cmp(common,dir) ) ){ 
 			return ..string.right(path,-( #common + 1 + (prefix?-1:0)) ); 
 		}
 	}
 	replaceDir = function(path,dir,newDir){ 
		return  ..fsys.joinpath(newDir,relative(path,dir) );
	}
	replaceFile = function(path,newFile){ 
		return  ..fsys.joinpath(..fsys.getParentDir(path),newFile);
	}	
 	validName = function(name){
 		var name,count = ..string.replace(name,"[\\/:*?""<>|]","")
 		return !count,name
 	} 
} 

/**intellisense(fsys)
formatSize(.(字节长度) = 转换字节长度到适合的最大单位( bytes,KB,MB,GB等 )
formatSize(.(字节长度低位,字节长度高位) = 转换字节长度到适合的最大单位( bytes,KB,MB,GB等 )\n低位用于表示4GB以下的长度,高位以4GB为最小单位表示长度,
end intellisense**/

/**intellisense(fsys.path) 
cmp(.(路径,比较路径) = 比较两个路径是否指向同一位置,\n返回值意义与 string.cmp()函数相同,\n路径相同则返回0,注意在条件表达式中为false
compact(.(文件路径,显示像素宽度) = 截断路径来适合一定数目的像素
commonPrefix(.(路径,路径2) = 返回两个文件路径的公共前缀目录\n该函数失败保证返回的是一个目录比以斜杠结尾,失败返回null,\n在比较以前自动对路径归一化处理,忽略大小写
canonicalize(__/*路径*/) = 对路径进行归一化处理,\n扩展和适当置换路径中包含的所有".."和"."\n该函数保证路径尾部总是不使用斜框.
addBackslash(__/*路径*/) = 在目录路径后添加"\"
relative(.(路径,目录,返回路径首字符是否为斜杠) = 将路径转换为指定目录下的相对路径,\n在比较以前自动对路径归一化处理,忽略大小写\n相同路径则返回空字符串,不是该目录下的路径则返回null\n参数三可选,默认首字符为斜杠
validName(__/*路径*/) = 检测文件名是否合法,\n包含非法字符返回false,以及修正后的合法名称
replaceDir(.(路径,根目录,新的根目录) = 将路径转换为参数2指定根目录下的相对路径\n再将其转换为新的根目录下的绝对路径
replaceFile(.(路径,新文件名) = 替换路径中的文件名部份
end intellisense**/


/**intellisense()
_FOF_ALLOWUNDO=@0x40/*_FOF_ALLOWUNDO*/ //允许撤销 
_FOF_FILESONLY=@0x80/*_FOF_FILESONLY*/ //使用 *.* 时, 只对文件操作 
_FOF_NOCONFIRMATION=@0x10/*_FOF_NOCONFIRMATION*/ //不对用户显示提示 
_FOF_NOCONFIRMMKDIR=@0x200/*_FOF_NOCONFIRMMKDIR*/ //建新目录时不需要用户确定 
_FOF_RENAMEONCOLLISION=@0x8/*_FOF_RENAMEONCOLLISION*/ //碰到有抵触的名字时，自动分配前缀 
_FOF_SILENT=@0x4/*_FOF_SILENT*/ //不显示一个进度对话框 
_FOF_NOERRORUI=@0x0400/*_FOF_NOERRORUI*/ //不显示出错用户界面 
_FOF_SIMPLEPROGRESS=@0x100/*_FOF_SIMPLEPROGRESS*/ //简单进度条，意味者不显示文件名。 
_FOF_NORECURSION =@0x1000/*_FOF_NORECURSION*/ //不递归目录 
_FOF_NOCOPYSECURITYATTRIBS =@0x0800/*_FOF_NOCOPYSECURITYATTRIBS */ //不复制 NT 文件的安全属性 
_FOF_WANTMAPPINGHANDLE=@0x20/*_FOF_WANTMAPPINGHANDLE*/
_FOF_CONFIRMMOUSE=@0x2/*_FOF_CONFIRMMOUSE*/ 
_CSIDL_DESKTOP  = @0 /*_CSIDL_DESKTOP*/ // <desktop>
_CSIDL_INTERNET  = @0x1 /*_CSIDL_INTERNET*/ // Internet Explorer (icon on desktop)
_CSIDL_PROGRAMS  = @0x2 /*_CSIDL_PROGRAMS*/ // Start Menu\Programs
_CSIDL_CONTROLS  = @0x3 /*_CSIDL_CONTROLS*/ // My Computer\Control Panel
_CSIDL_PRINTERS  = @0x4 /*_CSIDL_PRINTERS*/ // My Computer\Printers
_CSIDL_PERSONAL  = @0x5 /*_CSIDL_PERSONAL*/ // My Documents
_CSIDL_FAVORITES  = @0x6 /*_CSIDL_FAVORITES*/ // <user name>\Favorites
_CSIDL_STARTUP  = @0x7 /*_CSIDL_STARTUP*/ // Start Menu\Programs\Startup
_CSIDL_RECENT  = @0x8 /*_CSIDL_RECENT*/ // <user name>\Recent
_CSIDL_SENDTO  = @0x9 /*_CSIDL_SENDTO*/ // <user name>\SendTo
_CSIDL_BITBUCKET  = @0xa /*_CSIDL_BITBUCKET*/ // <desktop>\Recycle Bin
_CSIDL_STARTMENU  = @0xb /*_CSIDL_STARTMENU*/ // <user name>\Start Menu
_CSIDL_MYDOCUMENTS  = @0x5 /*_CSIDL_MYDOCUMENTS*/ // Personal was just a silly name for My Documents
_CSIDL_MYMUSIC  = @0xd /*_CSIDL_MYMUSIC*/ // "My Music" folder
_CSIDL_MYVIDEO  = @0xe /*_CSIDL_MYVIDEO*/ // "My Videos" folder
_CSIDL_DESKTOPDIRECTORY = @0x10 /*_CSIDL_DESKTOPDIRECTORY*/ // <user name>\Desktop
_CSIDL_DRIVES  = @0x11 /*_CSIDL_DRIVES*/ // My Computer
_CSIDL_NETWORK  = @0x12 /*_CSIDL_NETWORK*/ // Network Neighborhood (My Network Places)
_CSIDL_NETHOOD  = @0x13 /*_CSIDL_NETHOOD*/ // <user name>\nethood
_CSIDL_FONTS  = @0x14 /*_CSIDL_FONTS*/ // windows\fonts
_CSIDL_TEMPLATES  = @0x15
_CSIDL_COMMON_STARTMENU = @0x16 /*_CSIDL_COMMON_STARTMENU*/ // All Users\Start Menu
_CSIDL_COMMON_PROGRAMS = @0x17 /*_CSIDL_COMMON_PROGRAMS*/ // All Users\Start Menu\Programs
_CSIDL_COMMON_STARTUP = @0x18 /*_CSIDL_COMMON_STARTUP*/ // All Users\Startup
_CSIDL_COMMON_DESKTOPDIRECTORY = @0x19 /*_CSIDL_COMMON_DESKTOPDIRECTORY*/ // All Users\Desktop
_CSIDL_APPDATA  = @0x1a /*_CSIDL_APPDATA*/ // <user name>\Application Data
_CSIDL_PRINTHOOD  = @0x1b /*_CSIDL_PRINTHOOD*/ // <user name>\PrintHood
_CSIDL_LOCAL_APPDATA = @0x1c /*_CSIDL_LOCAL_APPDATA*/ // <user name>\Local Settings\Applicaiton Data (non roaming)
_CSIDL_ALTSTARTUP = @0x1d /*_CSIDL_ALTSTARTUP*/ // non localized startup
_CSIDL_COMMON_ALTSTARTUP = @0x1e /*_CSIDL_COMMON_ALTSTARTUP*/ // non localized common startup
_CSIDL_COMMON_FAVORITES = @0x1f
_CSIDL_INTERNET_CACHE = @0x20
_CSIDL_COOKIES  = @0x21
_CSIDL_HISTORY  = @0x22
_CSIDL_COMMON_APPDATA = @0x23 /*_CSIDL_COMMON_APPDATA*/ // All Users\Application Data
_CSIDL_WINDOWS  = @0x24 /*_CSIDL_WINDOWS*/ // GetWindowsDirectory()
_CSIDL_SYSTEM  = @0x25 /*_CSIDL_SYSTEM*/ // GetSystemDirectory()
_CSIDL_PROGRAM_FILES = @0x26 /*_CSIDL_PROGRAM_FILES*/ // C:\Program Files
_CSIDL_MYPICTURES = @0x27 /*_CSIDL_MYPICTURES*/ // C:\Program Files\My Pictures
_CSIDL_PROFILE  = @0x28 /*_CSIDL_PROFILE*/ // USERPROFILE
_CSIDL_SYSTEMX86  = @0x29 /*_CSIDL_SYSTEMX86*/ // x86 system directory on RISC
_CSIDL_PROGRAM_FILESX86 = @0x2a /*_CSIDL_PROGRAM_FILESX86*/ // x86 C:\Program Files on RISC
_CSIDL_PROGRAM_FILES_COMMON = @0x2b /*_CSIDL_PROGRAM_FILES_COMMON*/ // C:\Program Files\Common
_CSIDL_PROGRAM_FILES_COMMONX86 = @0x2c /*_CSIDL_PROGRAM_FILES_COMMONX86*/ // x86 Program Files\Common on RISC
_CSIDL_COMMON_TEMPLATES = @0x2d /*_CSIDL_COMMON_TEMPLATES*/ // All Users\Templates
_CSIDL_COMMON_DOCUMENTS = @0x2e /*_CSIDL_COMMON_DOCUMENTS*/ // All Users\Documents
_CSIDL_COMMON_ADMINTOOLS = @0x2f /*_CSIDL_COMMON_ADMINTOOLS*/ // All Users\Start Menu\Programs\Administrative Tools
_CSIDL_ADMINTOOLS = @0x30 /*_CSIDL_ADMINTOOLS*/ // <user name>\Start Menu\Programs\Administrative Tools
_CSIDL_CONNECTIONS = @0x31 /*_CSIDL_CONNECTIONS*/ // Network and Dial-up Connections
_CSIDL_COMMON_MUSIC = @0x35 /*_CSIDL_COMMON_MUSIC*/ // All Users\My Music
_CSIDL_COMMON_PICTURES = @0x36 /*_CSIDL_COMMON_PICTURES*/ // All Users\My Pictures
_CSIDL_COMMON_VIDEO = @0x37 /*_CSIDL_COMMON_VIDEO*/ // All Users\My Video
_CSIDL_RESOURCES  = @0x38 /*_CSIDL_RESOURCES*/ // Resource Direcotry
_CSIDL_RESOURCES_LOCALIZED = @0x39 /*_CSIDL_RESOURCES_LOCALIZED*/ // Localized Resource Direcotry
_CSIDL_COMMON_OEM_LINKS = @0x3a /*_CSIDL_COMMON_OEM_LINKS*/ // Links to All Users OEM specific apps
_CSIDL_CDBURN_AREA = @0x3b /*_CSIDL_CDBURN_AREA*/ // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
_CSIDL_COMPUTERSNEARME = @0x3d /*_CSIDL_COMPUTERSNEARME*/ // Computers Near Me (computered from Workgroup membership)
_CSIDL_FLAG_CREATE = @0x8000 /*_CSIDL_FLAG_CREATE*/ // combine with _CSIDL_ value to force folder creation in SHGetFolderPath()
_CSIDL_FLAG_DONT_VERIFY = @0x4000 /*_CSIDL_FLAG_DONT_VERIFY*/ // combine with _CSIDL_ value to return an unverified folder path
_CSIDL_FLAG_DONT_UNEXPAND = @0x2000 /*_CSIDL_FLAG_DONT_UNEXPAND*/ // combine with _CSIDL_ value to avoid unexpanding environment variables
_CSIDL_FLAG_NO_ALIAS = @0x1000 /*_CSIDL_FLAG_NO_ALIAS*/ // combine with _CSIDL_ value to insure non-alias versions of the pidl
_CSIDL_FLAG_PER_USER_INIT = @0x800 /*_CSIDL_FLAG_PER_USER_INIT*/ // combine with _CSIDL_ value to indicate per-user init (eg. upgrade)
_CSIDL_FLAG_MASK  = @0xFF00 /*_CSIDL_FLAG_MASK*/ // mask for all possible flag values
end intellisense**/