[Bf-blender-cvs] [721a9bc35c3] master: Fix T97338: Correct reference count for COM handling and removal of gotos
Robert Guetzkow
noreply at git.blender.org
Tue Apr 19 16:41:03 CEST 2022
Commit: 721a9bc35c3fed923c6cf5cfe1052d9cda168fd5
Author: Robert Guetzkow
Date: Tue Apr 19 16:27:19 2022 +0200
Branches: master
https://developer.blender.org/rB721a9bc35c3fed923c6cf5cfe1052d9cda168fd5
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
===================================================================
M source/blender/blenlib/intern/fileops.c
===================================================================
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);
}
More information about the Bf-blender-cvs
mailing list