mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[SHIMGVW] Unlock file (#6181)
- Add m_pMemStream to PREVIEW_DATA structure. - Add Preview_pFreeImage helper function. - Add MemStreamFromFile helper function to make a memory stream. - Avoid file locking by using a memory stream and GdipLoadImageFromStream. CORE-19183
This commit is contained in:
parent
e8f9564c20
commit
b6274fdde1
1 changed files with 66 additions and 31 deletions
|
@ -105,6 +105,7 @@ typedef struct tagPREVIEW_DATA
|
|||
INT m_yScrollOffset;
|
||||
UINT m_nMouseDownMsg;
|
||||
POINT m_ptOrigin;
|
||||
IStream *m_pMemStream;
|
||||
} PREVIEW_DATA, *PPREVIEW_DATA;
|
||||
|
||||
static inline PPREVIEW_DATA
|
||||
|
@ -328,7 +329,7 @@ Preview_UpdateTitle(PPREVIEW_DATA pData, LPCWSTR FileName)
|
|||
}
|
||||
|
||||
static VOID
|
||||
Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName)
|
||||
Preview_pFreeImage(PPREVIEW_DATA pData)
|
||||
{
|
||||
Anime_FreeInfo(&pData->m_Anime);
|
||||
|
||||
|
@ -338,6 +339,51 @@ Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName)
|
|||
g_pImage = NULL;
|
||||
}
|
||||
|
||||
if (pData->m_pMemStream)
|
||||
{
|
||||
pData->m_pMemStream->lpVtbl->Release(pData->m_pMemStream);
|
||||
pData->m_pMemStream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IStream* MemStreamFromFile(LPCWSTR pszFileName)
|
||||
{
|
||||
HANDLE hFile;
|
||||
DWORD dwFileSize, dwRead;
|
||||
LPBYTE pbMemFile = NULL;
|
||||
IStream *pStream;
|
||||
|
||||
hFile = CreateFileW(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
|
||||
dwFileSize = GetFileSize(hFile, NULL);
|
||||
pbMemFile = QuickAlloc(dwFileSize, FALSE);
|
||||
if (!dwFileSize || (dwFileSize == INVALID_FILE_SIZE) || !pbMemFile)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ReadFile(hFile, pbMemFile, dwFileSize, &dwRead, NULL) || (dwRead != dwFileSize))
|
||||
{
|
||||
QuickFree(pbMemFile);
|
||||
CloseHandle(hFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
pStream = SHCreateMemStream(pbMemFile, dwFileSize);
|
||||
QuickFree(pbMemFile);
|
||||
return pStream;
|
||||
}
|
||||
|
||||
static VOID
|
||||
Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName)
|
||||
{
|
||||
Preview_pFreeImage(pData);
|
||||
|
||||
/* check file presence */
|
||||
if (!szOpenFileName || GetFileAttributesW(szOpenFileName) == 0xFFFFFFFF)
|
||||
{
|
||||
|
@ -346,11 +392,21 @@ Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName)
|
|||
return;
|
||||
}
|
||||
|
||||
/* load now */
|
||||
GdipLoadImageFromFile(szOpenFileName, &g_pImage);
|
||||
pData->m_pMemStream = MemStreamFromFile(szOpenFileName);
|
||||
if (!pData->m_pMemStream)
|
||||
{
|
||||
DPRINT1("MemStreamFromFile() failed\n");
|
||||
Preview_UpdateTitle(pData, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: GdipLoadImageFromFile locks the file.
|
||||
Avoid file locking by using GdipLoadImageFromStream and memory stream. */
|
||||
GdipLoadImageFromStream(pData->m_pMemStream, &g_pImage);
|
||||
if (!g_pImage)
|
||||
{
|
||||
DPRINT1("GdipLoadImageFromFile() failed\n");
|
||||
DPRINT1("GdipLoadImageFromStream() failed\n");
|
||||
Preview_pFreeImage(pData);
|
||||
Preview_UpdateTitle(pData, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -1221,21 +1277,12 @@ Preview_Delete(PPREVIEW_DATA pData)
|
|||
GetFullPathNameW(g_pCurrentFile->Next->FileName, _countof(szNextFile), szNextFile, NULL);
|
||||
szNextFile[_countof(szNextFile) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
|
||||
|
||||
/* FIXME: Our GdipLoadImageFromFile locks the image file */
|
||||
if (g_pImage)
|
||||
{
|
||||
GdipDisposeImage(g_pImage);
|
||||
g_pImage = NULL;
|
||||
}
|
||||
|
||||
/* Confirm file deletion and delete if allowed */
|
||||
FileOp.pFrom = szCurFile;
|
||||
FileOp.fFlags = FOF_ALLOWUNDO;
|
||||
if (SHFileOperationW(&FileOp) != 0)
|
||||
{
|
||||
DPRINT("Preview_Delete: SHFileOperationW() failed or canceled\n");
|
||||
|
||||
Preview_pLoadImage(pData, szCurFile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1254,14 +1301,6 @@ Preview_Edit(HWND hwnd)
|
|||
if (!g_pCurrentFile)
|
||||
return;
|
||||
|
||||
/* Avoid file locking */
|
||||
/* FIXME: Our GdipLoadImageFromFile locks the image file */
|
||||
if (g_pImage)
|
||||
{
|
||||
GdipDisposeImage(g_pImage);
|
||||
g_pImage = NULL;
|
||||
}
|
||||
|
||||
GetFullPathNameW(g_pCurrentFile->FileName, _countof(szPathName), szPathName, NULL);
|
||||
szPathName[_countof(szPathName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
|
||||
|
||||
|
@ -1274,9 +1313,11 @@ Preview_Edit(HWND hwnd)
|
|||
{
|
||||
DPRINT1("Preview_Edit: ShellExecuteExW() failed with code %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
// Destroy the window to quit the application
|
||||
DestroyWindow(hwnd);
|
||||
else
|
||||
{
|
||||
// Destroy the window to quit the application
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
|
@ -1435,13 +1476,7 @@ Preview_OnDestroy(HWND hwnd)
|
|||
pFreeFileList(g_pCurrentFile);
|
||||
g_pCurrentFile = NULL;
|
||||
|
||||
if (g_pImage)
|
||||
{
|
||||
GdipDisposeImage(g_pImage);
|
||||
g_pImage = NULL;
|
||||
}
|
||||
|
||||
Anime_FreeInfo(&pData->m_Anime);
|
||||
Preview_pFreeImage(pData);
|
||||
|
||||
SetWindowLongPtrW(pData->m_hwndZoom, GWLP_USERDATA, 0);
|
||||
DestroyWindow(pData->m_hwndZoom);
|
||||
|
|
Loading…
Reference in a new issue