| 163 | } |
| 164 | |
| 165 | FLT_PREOP_CALLBACK_STATUS DelProtectPreSetInformation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID*) { |
| 166 | UNREFERENCED_PARAMETER(FltObjects); |
| 167 | |
| 168 | if (Data->RequestorMode == KernelMode) |
| 169 | return FLT_PREOP_SUCCESS_NO_CALLBACK; |
| 170 | |
| 171 | auto status = FLT_PREOP_SUCCESS_NO_CALLBACK; |
| 172 | auto& params = Data->Iopb->Parameters.SetFileInformation; |
| 173 | if (params.FileInformationClass == FileDispositionInformation || |
| 174 | params.FileInformationClass == FileDispositionInformationEx) { |
| 175 | auto info = (FILE_DISPOSITION_INFORMATION*)params.InfoBuffer; |
| 176 | if (info->DeleteFile & FILE_DISPOSITION_DELETE) {// also covers FileDispositionInformationEx |
| 177 | PFLT_FILE_NAME_INFORMATION fi; |
| 178 | // |
| 179 | // using FLT_FILE_NAME_NORMALIZED is important here for parsing purposes |
| 180 | // |
| 181 | if (NT_SUCCESS(FltGetFileNameInformation(Data, |
| 182 | FLT_FILE_NAME_QUERY_DEFAULT | FLT_FILE_NAME_NORMALIZED, |
| 183 | &fi))) { |
| 184 | if (!IsDeleteAllowed(&fi->Name)) { |
| 185 | Data->IoStatus.Status = STATUS_ACCESS_DENIED; |
| 186 | LogInfo("(Pre Set Information) Prevent deletion of %wZ\n", &fi->Name); |
| 187 | status = FLT_PREOP_COMPLETE; |
| 188 | } |
| 189 | FltReleaseFileNameInformation(fi); |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | return status; |
| 195 | } |
| 196 | |
| 197 | bool IsDeleteAllowed(PCUNICODE_STRING filename) { |
| 198 | UNICODE_STRING ext; |
nothing calls this directly
no test coverage detected