Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Guetzkow <rjg>2022-04-19 17:27:19 +0300
committerRobert Guetzkow <gitcommit@outlook.de>2022-04-19 17:30:22 +0300
commit721a9bc35c3fed923c6cf5cfe1052d9cda168fd5 (patch)
treef678789f8e966287ed82114076d17b61262cb457 /source/blender/blenlib/intern
parent3e98331a094b0bc7f6bf8d386e610e06bfa4e61b (diff)
Fix T97338: Correct reference count for COM handling and removal of gotos
The fix ensures that the reference count for `IShellItem *pSI` is decremented, preventing a memory leak. For `IFileOperation *pfo` the decrement of the reference count is only attempted when `CoCreateInstance` is successful. Additionally, the gotos have been replaced with nested if/else statements. Reviewed By: brecht Differential Revision: https://developer.blender.org/D14681
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/fileops.c92
1 files changed, 48 insertions, 44 deletions
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 26a0479f445..5ca6fe2efd0 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -301,56 +301,60 @@ static bool delete_soft(const wchar_t *path_16, const char **error_message)
/* Deletes file or directory to recycling bin. The latter moves all contained files and
* directories recursively to the recycling bin as well. */
IFileOperation *pfo;
- IShellItem *pSI;
+ IShellItem *psi;
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
- if (FAILED(hr)) {
- *error_message = "Failed to initialize COM";
- goto error_1;
- }
-
- hr = CoCreateInstance(
- &CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, (void **)&pfo);
- if (FAILED(hr)) {
- *error_message = "Failed to create FileOperation instance";
- goto error_2;
- }
-
- /* Flags for deletion:
- * FOF_ALLOWUNDO: Enables moving file to recycling bin.
- * FOF_SILENT: Don't show progress dialog box.
- * FOF_WANTNUKEWARNING: Show dialog box if file can't be moved to recycling bin. */
- hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING);
-
- if (FAILED(hr)) {
- *error_message = "Failed to set operation flags";
- goto error_2;
- }
-
- hr = SHCreateItemFromParsingName(path_16, NULL, &IID_IShellItem, (void **)&pSI);
- if (FAILED(hr)) {
- *error_message = "Failed to parse path";
- goto error_2;
- }
-
- hr = pfo->lpVtbl->DeleteItem(pfo, pSI, NULL);
- if (FAILED(hr)) {
- *error_message = "Failed to prepare delete operation";
- goto error_2;
+ if (SUCCEEDED(hr)) {
+ /* This is also the case when COM was previously initialized and CoInitializeEx returns
+ * S_FALSE, which is not an error. Both HRESULT values S_OK and S_FALSE indicate success. */
+
+ hr = CoCreateInstance(
+ &CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, (void **)&pfo);
+
+ if (SUCCEEDED(hr)) {
+ /* Flags for deletion:
+ * FOF_ALLOWUNDO: Enables moving file to recycling bin.
+ * FOF_SILENT: Don't show progress dialog box.
+ * FOF_WANTNUKEWARNING: Show dialog box if file can't be moved to recycling bin. */
+ hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING);
+
+ if (SUCCEEDED(hr)) {
+ hr = SHCreateItemFromParsingName(path_16, NULL, &IID_IShellItem, (void **)&psi);
+
+ if (SUCCEEDED(hr)) {
+ hr = pfo->lpVtbl->DeleteItem(pfo, psi, NULL);
+
+ if (SUCCEEDED(hr)) {
+ hr = pfo->lpVtbl->PerformOperations(pfo);
+
+ if (FAILED(hr)) {
+ *error_message = "Failed to prepare delete operation";
+ }
+ }
+ else {
+ *error_message = "Failed to prepare delete operation";
+ }
+ psi->lpVtbl->Release(psi);
+ }
+ else {
+ *error_message = "Failed to parse path";
+ }
+ }
+ else {
+ *error_message = "Failed to set operation flags";
+ }
+ pfo->lpVtbl->Release(pfo);
+ }
+ else {
+ *error_message = "Failed to create FileOperation instance";
+ }
+ CoUninitialize();
}
-
- hr = pfo->lpVtbl->PerformOperations(pfo);
-
- if (FAILED(hr)) {
- *error_message = "Failed to delete file or directory";
+ else {
+ *error_message = "Failed to initialize COM";
}
-error_2:
- pfo->lpVtbl->Release(pfo);
- CoUninitialize(); /* Has to be uninitialized when CoInitializeEx returns either S_OK or S_FALSE
- */
-error_1:
return FAILED(hr);
}