| 1086 | // |
| 1087 | |
| 1088 | bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope) |
| 1089 | { |
| 1090 | TMPQArchive * ha = IsValidMpqHandle(hMpq); |
| 1091 | TMPQFile * hf = NULL; |
| 1092 | DWORD dwErrCode = ERROR_SUCCESS; |
| 1093 | |
| 1094 | // Keep compiler happy |
| 1095 | dwSearchScope = dwSearchScope; |
| 1096 | |
| 1097 | // Check the parameters |
| 1098 | if(ha == NULL) |
| 1099 | dwErrCode = ERROR_INVALID_HANDLE; |
| 1100 | if(szFileName == NULL || *szFileName == 0) |
| 1101 | dwErrCode = ERROR_INVALID_PARAMETER; |
| 1102 | if(IsInternalMpqFileName(szFileName)) |
| 1103 | dwErrCode = ERROR_INTERNAL_FILE; |
| 1104 | |
| 1105 | // Do not allow to remove files from read-only or patched MPQs |
| 1106 | if(dwErrCode == ERROR_SUCCESS) |
| 1107 | { |
| 1108 | if((ha->dwFlags & MPQ_FLAG_READ_ONLY) || (ha->haPatch != NULL)) |
| 1109 | dwErrCode = ERROR_ACCESS_DENIED; |
| 1110 | } |
| 1111 | |
| 1112 | // If all checks have passed, we can delete the file from the MPQ |
| 1113 | if(dwErrCode == ERROR_SUCCESS) |
| 1114 | { |
| 1115 | // Open the file from the MPQ |
| 1116 | if(SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hf)) |
| 1117 | { |
| 1118 | // Delete the file entry |
| 1119 | dwErrCode = DeleteFileEntry(ha, hf); |
| 1120 | FreeFileHandle(hf); |
| 1121 | } |
| 1122 | else |
| 1123 | dwErrCode = GetLastError(); |
| 1124 | } |
| 1125 | |
| 1126 | // If the file has been deleted, we need to invalidate |
| 1127 | // the internal files and recreate HET table |
| 1128 | if(dwErrCode == ERROR_SUCCESS) |
| 1129 | { |
| 1130 | // Invalidate the entries for internal files |
| 1131 | // After we are done with MPQ changes, we need to re-create them anyway |
| 1132 | InvalidateInternalFiles(ha); |
| 1133 | |
| 1134 | // |
| 1135 | // Don't rebuild HET table now; the file's flags indicate |
| 1136 | // that it's been deleted, which is enough |
| 1137 | // |
| 1138 | } |
| 1139 | |
| 1140 | // Resolve error and exit |
| 1141 | if(dwErrCode != ERROR_SUCCESS) |
| 1142 | SetLastError(dwErrCode); |
| 1143 | return (dwErrCode == ERROR_SUCCESS); |
| 1144 | } |
| 1145 | |