/* (C) 2003-2007 Willem Jan Hengeveld * Web: http://www.xs4all.nl/~itsme/ * http://wiki.xda-developers.com/ * * $Id: pdel.cpp 1749 2008-03-11 17:12:13Z itsme $ * * this program allows you to delete files or directories on a windows ce * device * */ #include #include #include #include #include "debug.h" #include "args.h" #include "csidlpaths.h" #include "stringutils.h" #define AT_NONEXISTANT 1 #define AT_ISDIRECTORY 2 #define AT_ISFILE 3 int getCeAttributes(const std::string& name) { DWORD dwAttr = CeGetFileAttributes( expand_csidl(ToWString(name)).c_str() ); if (0xFFFFFFFF == dwAttr) return AT_NONEXISTANT; if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) return AT_ISDIRECTORY; return AT_ISFILE; } bool isCeDirectory(const std::string& name) { return getCeAttributes(name)==AT_ISDIRECTORY; } bool isCeFile(const std::string& name) { return getCeAttributes(name)==AT_ISFILE; } bool isCeNonExistant(const std::string& name) { return getCeAttributes(name)==AT_NONEXISTANT; } std::string concat_path(const std::string& p1, const std::string& p2) { std::string result(p1); if (result.size() && result[result.size()-1]!='/' && result[result.size()-1]!='\\') result += '\\'; result += p2; return result; } std::string GetBasePath(const std::string& name) { size_t lastslash= name.find_last_of("\\/"); if (lastslash==name.npos) return ""; return name.substr(0, lastslash); } bool CeFileGlob(const std::string& name, StringList& filelist, StringList& dirlist) { CE_FIND_DATA wfd; HANDLE hFind = CeFindFirstFile( expand_csidl(ToWString(name)).c_str(), &wfd); if (INVALID_HANDLE_VALUE == hFind) return false; std::string rootpath= GetBasePath(name); do { std::string fullpath= concat_path(rootpath, ToString(wfd.cFileName)); if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) dirlist.push_back(fullpath); else filelist.push_back(fullpath); } while (CeFindNextFile(hFind, &wfd)); CeFindClose(hFind); return true; } bool hasWildCards(const std::string& name) { return name.find_first_of("*?")!=name.npos; } void usage() { printf("(C) 2003-2008 Willem jan Hengeveld itsme@xs4all.nl\n"); printf("Usage: pdel [-r] [-d root ] file [ file ...]\n"); printf(" -d may be specified multiple times\n"); printf(" -r : recurse\n"); printf(" the most recent -d option is the current dir for a file\n"); } #define isSlash(c) ((c)=='/' || (c)=='\\') void StripTrailingSlashes(char *fn) { char *p= fn+strlen(fn)-1; while (p>=fn && isSlash(*p)) *p-- = 0; } bool DeleteCeFile(const std::string& filename) { CeSetFileAttributes(expand_csidl(ToWString(filename)).c_str(), 0); if (!CeDeleteFile(expand_csidl(ToWString(filename)).c_str())) { ceerror("DeleteFile %s", filename.c_str()); return false; } return true; } bool RemoveCeDirectory(const std::string& dirname, bool bRecurse) { if (bRecurse) { StringList files; StringList subdirs; if (!CeFileGlob(concat_path(dirname,"*"), files, subdirs)) { debug("error getting dir contents %s\n", dirname.c_str()); } else { for (StringList::iterator i= files.begin() ; i!=files.end() ; ++i) DeleteCeFile(*i); for (StringList::iterator i= subdirs.begin() ; i!=subdirs.end() ; ++i) RemoveCeDirectory(*i, bRecurse); } } if (!CeRemoveDirectory(expand_csidl(ToWString(dirname)).c_str())) { ceerror("RemoveDirectory %s", dirname.c_str()); return false; } return true; } int main( int argc, char *argv[]) { DebugStdOut(); std::string curDirectory; bool bRecurse= false; StringList filelist; int argsfound=0; for (int i=1 ; i