#include #include "args.h" #include "debug.h" #include "stringutils.h" #include "vectorutils.h" #include "CEIOCTL.h" std::string FLStatus_string(FLStatus status) { switch(status) { case flOK: return "flOK"; case flBadFunction: return "flBadFunction"; case flFileNotFound: return "flFileNotFound"; case flPathNotFound: return "flPathNotFound"; case flTooManyOpenFiles: return "flTooManyOpenFiles"; case flNoWriteAccess: return "flNoWriteAccess"; case flBadFileHandle: return "flBadFileHandle"; case flDriveNotAvailable: return "flDriveNotAvailable"; case flNonFATformat: return "flNonFATformat"; case flFormatNotSupported: return "flFormatNotSupported"; case flNoMoreFiles: return "flNoMoreFiles"; case flWriteProtect: return "flWriteProtect"; case flBadDriveHandle: return "flBadDriveHandle"; case flDriveNotReady: return "flDriveNotReady"; case flUnknownCmd: return "flUnknownCmd"; case flBadFormat: return "flBadFormat"; case flBadLength: return "flBadLength"; case flDataError: return "flDataError"; case flUnknownMedia: return "flUnknownMedia"; case flSectorNotFound: return "flSectorNotFound"; case flOutOfPaper: return "flOutOfPaper"; case flWriteFault: return "flWriteFault"; case flReadFault: return "flReadFault"; case flGeneralFailure: return "flGeneralFailure"; case flDiskChange: return "flDiskChange"; case flVppFailure: return "flVppFailure"; case flBadParameter: return "flBadParameter"; case flNoSpaceInVolume: return "flNoSpaceInVolume"; case flInvalidFATchain: return "flInvalidFATchain"; case flRootDirectoryFull: return "flRootDirectoryFull"; case flNotMounted: return "flNotMounted"; case flPathIsRootDirectory: return "flPathIsRootDirectory"; case flNotADirectory: return "flNotADirectory"; case flDirectoryNotEmpty: return "flDirectoryNotEmpty"; case flFileIsADirectory: return "flFileIsADirectory"; case flAdapterNotFound: return "flAdapterNotFound"; case flFormattingError: return "flFormattingError"; case flNotEnoughMemory: return "flNotEnoughMemory"; case flVolumeTooSmall: return "flVolumeTooSmall"; case flBufferingError: return "flBufferingError"; case flFileAlreadyExists: return "flFileAlreadyExists"; case flIncomplete: return "flIncomplete"; case flTimedOut: return "flTimedOut"; case flTooManyComponents: return "flTooManyComponents"; case flTooManyDrives: return "flTooManyDrives"; case flTooManyBinaryPartitions: return "flTooManyBinaryPartitions"; case flPartitionNotFound: return "flPartitionNotFound"; case flFeatureNotSupported: return "flFeatureNotSupported"; case flWrongVersion: return "flWrongVersion"; case flTooManyBadBlocks: return "flTooManyBadBlocks"; case flNotProtected: return "flNotProtected"; case flUnchangeableProtection: return "flUnchangeableProtection"; case flBadDownload: return "flBadDownload"; case flBadBBT: return "flBadBBT"; case flInterleaveError: return "flInterleaveError"; case flWrongKey: return "flWrongKey"; case flHWProtection: return "flHWProtection"; case flLeftForCompetability: return "flLeftForCompetability"; case flMultiDocContradiction: return "flMultiDocContradiction"; case flCanNotFold: return "flCanNotFold"; case flBadIPLBlock: return "flBadIPLBlock"; case flIOCommandBlocked: return "flIOCommandBlocked"; default: return stringformat("FLStatus_%d", status); } } typedef struct { char devicetype[10]; char operatorname[20]; char language[10]; } DEVDATASECTOR; std::string StringFromData(const char* ptr, int len) { std::string str; while (len-- && *ptr) str += *ptr++; return str; } void DataFromString(char* ptr, int len, const std::string& str) { for (int i=0 ; idevicetype, 10); operatorname= StringFromData(devdata->operatorname, 20); language = StringFromData(devdata->language, 10); return true; } bool UpdateDevdataSector(ByteVector& sector, const std::string& devicetype, const std::string& operatorname, const std::string& language) { DEVDATASECTOR *devdata= (DEVDATASECTOR *)vectorptr(sector); DataFromString(devdata->devicetype, 10, devicetype ); DataFromString(devdata->operatorname, 20, operatorname); DataFromString(devdata->language, 10, language ); return true; } bool ReadBDKSector(HANDLE hDsk, int sector, int nrsectors, ByteVector& buffer) { flBDKOperationInput in; memset(&in, 0, sizeof(in)); buffer.resize(0x8000*nrsectors); in.partitionNumber= 0; in.type= BDK_READ; in.bdkStruct.startingBlock= sector; in.bdkStruct.length= buffer.size(); //in.bdkStruct.bdkBuffer= vectorptr(buffer); DWORD nReturned=0; if (!DeviceIoControl(hDsk, FL_IOCTL_BDK_OPERATION, &in, sizeof(in), vectorptr(buffer), buffer.size(), &nReturned, NULL)) { error("FL_IOCTL_BDK_OPERATION:BDK_READ -ret=%d", nReturned); return false; } return true; } bool WriteBDKSector(HANDLE hDsk, int sector, const ByteVector& buffer) { flBDKOperationInput in; memset(&in, 0, sizeof(in)); flOutputStatusRecord out; memset(&out, 0, sizeof(out)); in.partitionNumber= 0; in.type= BDK_WRITE; in.bdkStruct.startingBlock= sector; in.bdkStruct.length= buffer.size(); in.bdkStruct.bdkBuffer= const_cast(vectorptr(buffer)); DWORD nReturned=0; if (!DeviceIoControl(hDsk, FL_IOCTL_BDK_OPERATION, &in, sizeof(in), &out, sizeof(out), &nReturned, NULL)) { error("FL_IOCTL_BDK_OPERATION:BDK_WRITE -ret=%d", nReturned); } debug("FL_IOCTL_BDK_OPERATION:BDK_WRITE status: %hs ret=%d\n", FLStatus_string(out.status).c_str(), nReturned); return true; } bool UpdateDeviceData(HANDLE hDsk, const std::string& new_devicetype, const std::string& new_operatorname, const std::string& new_language) { ByteVector sector; if (!ReadBDKSector(hDsk, 2, 1, sector)) return false; std::string dev_devicetype; std::string dev_operatorname; std::string dev_language; if (!ParseDevdataSector(sector,dev_devicetype, dev_operatorname, dev_language)) return false; debug("current: type=%hs op=%hs lang=%hs\n", dev_devicetype.c_str(), dev_operatorname.c_str(), dev_language.c_str()); if (!UpdateDevdataSector(sector, new_devicetype.empty()?dev_devicetype:new_devicetype, new_operatorname.empty()?dev_operatorname:new_operatorname, new_language.empty()?dev_language:new_language)) return false; if (!WriteBDKSector(hDsk, 2, sector)) return false; return true; } HANDLE OpenDisk(int n) { TCHAR diskname[16]; _sntprintf(diskname, 16, L"DSK%u:", n); HANDLE hDsk= CreateFile( diskname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (hDsk==NULL || hDsk==INVALID_HANDLE_VALUE) { return NULL; } return hDsk; } void usage() { debug("Usage: setdevdata [-o newoperator] [-l newlanguage] [-t devicetype]\n"); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("setdevdata.log"); std::string new_devicetype; std::string new_operatorname; std::string new_language; StringList args; if (!SplitString(ToString(lpCmdLine), args)) { debug("error parsing commandline: %ls\n", lpCmdLine); return 1; } int argsfound=0; for (StringList::iterator i= args.begin() ; i!=args.end() ; ++i) { std::string& arg= *i; if (arg[0]=='-') switch(arg[1]) { case 'd': HANDLESTLSTROPTION(new_devicetype); break; case 'o': HANDLESTLSTROPTION(new_operatorname); break; case 'l': HANDLESTLSTROPTION(new_language); break; default: usage(); return 1; } } HANDLE hDsk= OpenDisk(2); if (hDsk==NULL) { error("OpenDisk(DSK2:)"); return 1; } UpdateDeviceData(hDsk, new_devicetype, new_operatorname, new_language); CloseHandle(hDsk); return 0; }