Skip to content

Instantly share code, notes, and snippets.

@maxdeliso
Created September 6, 2012 22:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save maxdeliso/3660735 to your computer and use it in GitHub Desktop.
Save maxdeliso/3660735 to your computer and use it in GitHub Desktop.
search filesystem for writable files
#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