Created
September 6, 2012 22:08
-
-
Save maxdeliso/3660735 to your computer and use it in GitHub Desktop.
search filesystem for writable files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <Windows.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
void* fallibleMalloc(int n); | |
enum PROG_ERRCODES { | |
OP_OK = 0, | |
OP_BAD_FIRST_FILE = 1 << 1, | |
OP_BAD_DRIVESTRINGS = 1 << 2, | |
OP_BAD_LAST_FIND_FILE = 1 << 3, | |
OP_BAD_FIND_CLOSE = 1 << 4, | |
OP_FAILED = 0xffffffff | |
}; | |
enum PROG_ERRCODES walkDrives(); | |
enum PROG_ERRCODES walkDirectoryTree(const char* const rootDirectoryStar); | |
enum PROG_ERRCODES processFile(const TCHAR* const filePath, const WIN32_FIND_DATA* const fDataPtr ); | |
int main(int argc, char** argv) { | |
/* TODO: process command line arguments for optional start directory */ | |
return walkDrives(); | |
} | |
void* fallibleMalloc(int n) { | |
auto void* heapBlock = malloc(n); | |
assert(heapBlock); | |
return heapBlock; | |
} | |
enum PROG_ERRCODES walkDrives() { | |
auto int i; | |
auto int driveBufferLen = GetLogicalDriveStrings(0, NULL); | |
auto TCHAR* driveBuffer = (TCHAR*) fallibleMalloc(driveBufferLen+1); | |
if(!GetLogicalDriveStrings(driveBufferLen, driveBuffer)) { | |
free(driveBuffer); | |
return OP_BAD_DRIVESTRINGS; | |
} | |
for( i = 0; i < driveBufferLen; ++i) { | |
auto TCHAR* thisDriveString = NULL; | |
auto int startIndex = i; | |
auto int dLen = 0; | |
auto enum PROG_ERRCODES err; | |
while(driveBuffer[i] != 0) { ++i; } | |
dLen = i - startIndex + 1; | |
thisDriveString = (TCHAR*) fallibleMalloc(dLen+1+1); | |
strncpy(thisDriveString, driveBuffer + startIndex, dLen); | |
strcat(thisDriveString + startIndex + dLen - 1, "*"); | |
if(!(err = walkDirectoryTree((const char* const) thisDriveString))) { | |
free(thisDriveString); | |
return err; | |
} | |
free(thisDriveString); | |
} | |
free(driveBuffer); | |
return OP_OK; | |
} | |
enum PROG_ERRCODES walkDirectoryTree(const char* const rootDirectoryStar) { | |
static const char charSuffix[] = "\\*"; | |
static const int charSuffixLen = 2; | |
static const char symbolicDirName[] = "."; | |
static const char symbolicParentDirName[] = ".."; | |
auto WIN32_FIND_DATA fData; | |
auto HANDLE hFind; | |
printf("D %s\n", rootDirectoryStar); | |
if ((hFind = FindFirstFile(rootDirectoryStar, &fData)) == INVALID_HANDLE_VALUE) { | |
return OP_BAD_FIRST_FILE; | |
} | |
do { | |
auto int cFileNameLen = strlen(fData.cFileName); | |
auto int rootDirectoryStarLen = strlen(rootDirectoryStar); | |
/* skip the symbolic directories */ | |
if(strcmp(fData.cFileName, symbolicParentDirName) == 0 || strcmp(fData.cFileName, symbolicDirName) == 0) { | |
continue; | |
/* if we're dealing with a directory */ | |
} else if(fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { | |
int nextRootDirectoryStarLen = | |
(rootDirectoryStarLen - 1 ) + /* length of root directory, minus one */ | |
cFileNameLen + /* length of leaf directory */ | |
charSuffixLen + /* for slash star */ | |
1; /* for null terminator */ | |
auto enum PROG_ERRCODES err; | |
auto TCHAR* nextRootDirectoryStar = (TCHAR*) fallibleMalloc(nextRootDirectoryStarLen); | |
memset(nextRootDirectoryStar, '\0', nextRootDirectoryStarLen); | |
strncpy(nextRootDirectoryStar, rootDirectoryStar, rootDirectoryStarLen - 1); | |
strncat(nextRootDirectoryStar, fData.cFileName, cFileNameLen); | |
strncat(nextRootDirectoryStar, charSuffix, charSuffixLen); | |
if( !(err=walkDirectoryTree(nextRootDirectoryStar)) ) { | |
/* something went wrong */ | |
} | |
free(nextRootDirectoryStar); | |
/* otherwise treat it as a file */ | |
} else { | |
auto int cFilePathLen = rootDirectoryStarLen - 1 + cFileNameLen + 1; | |
auto TCHAR* cFilePath = (TCHAR*) fallibleMalloc(cFilePathLen); | |
auto enum PROG_ERRCODES err; | |
/* concatenate root directory star minus the star and cfile name | |
* then call processFile(..) with the newly formed string */ | |
memset(cFilePath, '\0', cFilePathLen); | |
strncpy(cFilePath, rootDirectoryStar, rootDirectoryStarLen - 1); | |
strncat(cFilePath, fData.cFileName, cFileNameLen); | |
if( !(err = processFile(cFilePath, (const WIN32_FIND_DATA* const) &fData ))) { | |
/* something went wrong */ | |
} | |
free(cFilePath); | |
} | |
} while (FindNextFile(hFind, &fData)); | |
if( GetLastError() != ERROR_NO_MORE_FILES ) { | |
if(!FindClose(hFind)) { | |
return OP_BAD_LAST_FIND_FILE; | |
} else { | |
return OP_BAD_LAST_FIND_FILE | OP_BAD_FIND_CLOSE; | |
} | |
} | |
if(!FindClose(hFind)) { | |
return OP_BAD_FIND_CLOSE; | |
} | |
return OP_OK; | |
} | |
enum PROG_ERRCODES processFile(const TCHAR* const filePath, const WIN32_FIND_DATA* const fDataPtr ) { | |
auto HANDLE fHandle; | |
printf("F %s ", filePath); | |
/* attempt to acquire write lock */ | |
if ((fHandle = CreateFile( | |
filePath, | |
GENERIC_READ | GENERIC_WRITE, | |
FILE_SHARE_WRITE, | |
NULL, | |
OPEN_EXISTING, | |
FILE_ATTRIBUTE_NORMAL, | |
NULL)) == INVALID_HANDLE_VALUE ) { | |
printf("NW\n"); | |
return OP_OK; | |
} | |
if(CloseHandle(fHandle)) { | |
printf("W\n"); | |
return OP_OK; | |
} else { | |
printf("EW\n"); | |
return OP_FAILED; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment