exp bool DirCreate(const char* dirName) { // Convert the filename into DOS8.3 format char* dosName = new char[12]; ToDos83Name(dirName, dosName); DirectoryEntry* entry = MakeEntry(dosName, ATTRIB_DIRECTORY, 0, &directory); if (!entry) { LastError("DirCreate", "Failed to create a directory"); delete[] dosName; return false; } // Write FAT entry FatEntry fatEntry; fatEntry.buffer = new char[bpb->bytesPerSector]; fatEntry.cluster = GetClusterFromEntry(entry); fatEntry.sector = GetFATSector(fatEntry.cluster); UpdateFAT(&fatEntry, GetClusterFromEntry(entry)); // Write entry to disk DirectoryWrite(&directory); //WriteSector(directoryBuffer + ((((char*)entry - directoryBuffer) / 512) * 512),directorySector + (((char*)entry - directoryBuffer) / 512)); delete[] dosName; delete[] fatEntry.buffer; return true; }
// Updates everything except for starting cluster and name // ONLY AFFECTS ENTRY, NOT FAT void UpdateEntry(DirectoryEntry* entry, const uint8_t attrib, const uint32_t size) { // Get the time time_t timestamp; struct tm* localTime; time(×tamp); localTime = localtime(×tamp); // Update the entry entry->attrib = (attrib) ? attrib : entry->attrib; entry->size = (size) ? size : entry->size; entry->lastModDate = CreateDate(localTime); entry->lastModTime = CreateTime(localTime); entry->accessDate = CreateDate(localTime); // Write to disk DirectoryWrite(&directory); //WriteSector(directoryBuffer + ((((char*)entry - directoryBuffer) / 512) * 512),directorySector + (((char*)entry - directoryBuffer) / 512)); }
exp bool Delete(const char* filename) { // Convert the filename into DOS8.3 format char* dosName = new char[12]; ToDos83Name(filename, dosName); // Find entry DirectoryEntry* entry = FindEntry(dosName, &directory); if (!entry) { LastError("Delete", "Failed to find file"); return false; } if (!(entry->attrib & ATTRIB_ARCHIVE) || (entry->attrib & ATTRIB_DIRECTORY)) { LastError("Delete", "This is not a file"); return false; } entry->name[0] = (char)ATTRIB_DELETED; DirectoryWrite(&directory); //WriteSector(directoryBuffer + ((((char*)entry - directoryBuffer) / 512) * 512),directorySector + (((char*)entry - directoryBuffer) / 512)); // Unlink all clusters FatEntry fatEntry; fatEntry.buffer = new char[bpb->bytesPerSector]; fatEntry.cluster = GetClusterFromEntry(entry); fatEntry.sector = GetFATSector(fatEntry.cluster); ReadSector(fatEntry.buffer, fatEntry.sector); while (DeleteCluster(&fatEntry)) Sleep(1); WriteSector(fatEntry.buffer, fatEntry.sector); delete[] fatEntry.buffer; return false; }
exp bool Rename(const char* old, const char* newname) { // Convert the filename into DOS8.3 format char* dosName = new char[12]; char* dosNameNew = new char[12]; ToDos83Name(old, dosName); ToDos83Name(newname, dosNameNew); // Find the entry DirectoryEntry* entry = FindEntry(dosName, &directory); if (!entry) { LastError("Rename", "Failed to find file"); return false; } memcpy(entry->name, dosNameNew, DOS83_MAX_LEN); DirectoryWrite(&directory); //WriteSector(directoryBuffer + ((((char*)entry - directoryBuffer) / 512) * 512),directorySector + (((char*)entry - directoryBuffer) / 512)); delete[] dosName; delete[] dosNameNew; return true; }
s32 GCMemcardDirectory::Write(u32 destaddress, s32 length, u8 *srcaddress) { std::unique_lock<std::mutex> l(m_write_mutex); if (length != 0x80) INFO_LOG(EXPANSIONINTERFACE, "WRITING TO %x, len %x", destaddress, length); s32 block = destaddress / BLOCK_SIZE; u32 offset = destaddress % BLOCK_SIZE; s32 extra = 0; // used for write calls that are across multiple blocks if (offset + length > BLOCK_SIZE) { extra = length + offset - BLOCK_SIZE; length -= extra; // verify that we haven't calculated a length beyond BLOCK_SIZE _dbg_assert_msg_(EXPANSIONINTERFACE, (destaddress + length) % BLOCK_SIZE == 0, "Memcard directory Write Logic Error"); } if (m_LastBlock != block) { switch (block) { case 0: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_hdr; break; case 1: case 2: { m_LastBlock = -1; s32 bytes_written = 0; while (length > 0) { s32 to_write = std::min<s32>(DENTRY_SIZE, length); bytes_written += DirectoryWrite(destaddress + bytes_written, to_write, srcaddress + bytes_written); length -= to_write; } return bytes_written; } case 3: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_bat1; break; case 4: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_bat2; break; default: m_LastBlock = SaveAreaRW(block, true); if (m_LastBlock == -1) { PanicAlertT("Report: GCIFolder Writing to unallocated block %x", block); exit(0); } } } memcpy(m_LastBlockAddress + offset, srcaddress, length); l.unlock(); if (extra) extra = Write(destaddress + length, extra, srcaddress + length); if (offset + length == BLOCK_SIZE) m_flush_trigger.Set(); return length + extra; }
exp bool CopyIn(const char* source, const char* dest) { DirectoryEntry* entry = 0; char* buffer = new char[bpb->bytesPerSector]; // Open file we're copying in std::ifstream inHandle(source, std::ios::in | std::ios::binary | std::ios::ate); if (!inHandle.is_open()) { LastError("CopyIn", "Failed to open source file"); return false; } // Get size of source file size_t inLength = (size_t)inHandle.tellg(); inHandle.seekg(std::ios::beg); // Convert the filename into DOS8.3 format char* dosName = new char[12]; ToDos83Name(dest, dosName); // Check if entry exists, if so, overwrite it entry = FindEntry(dosName, &directory); if (entry) { // Delete file Delete(dest); // Undelete entry entry->name[0] = dosName[0]; } // Create the directory entry if (!entry) { // Didn't delete file, make it entry = MakeEntry(dosName, ATTRIB_ARCHIVE, inLength, &directory); if (!entry) { LastError("CopyIn", "Failed to create directory entry"); delete[] dosName; delete[] buffer; return false; } } else { // Deleted file, find it entry = FindEntry(dosName, &directory); if (!entry) { LastError("CopyIn", "Somehow a file that was just undeleted can't be found..."); delete[] dosName; delete[] buffer; return false; } UpdateEntry(entry, 0, inLength); } // Write entry to disk DirectoryWrite(&directory); // Update FAT and then load each cluster and write it while updating the FAT FatEntry fatEntry; fatEntry.buffer = new char[bpb->bytesPerSector]; fatEntry.cluster = GetClusterFromEntry(entry); fatEntry.sector = GetFATSector(fatEntry.cluster); ReadSector(fatEntry.buffer, fatEntry.sector); UpdateFAT(&fatEntry, FindFreeCluster()); // Write to disk for (size_t i = 0; i < inLength; i += bpb->bytesPerSector) { memset(buffer, 0, bpb->bytesPerSector); if (!(i % bpb->bytesPerSector)) inHandle.read(buffer, bpb->bytesPerSector); else inHandle.read(buffer, i % bpb->bytesPerSector); WriteCluster(&fatEntry, buffer); } delete[] dosName; delete[] buffer; delete[] fatEntry.buffer; inHandle.close(); return true; }