Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,647 @@
/*
* Shell Library Functions
*
* Copyright 2005 Johannes Anderwald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
#define MAX_PROPERTY_SHEET_PAGE 32
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef struct
{
WCHAR Drive;
UINT Options;
UINT Result;
} FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT;
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
HPROPSHEETPAGE SH_CreatePropertySheetPage(LPCSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle);
static BOOL
GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNumberOfBytes)
{
DWORD ClusterSize;
if (!wcsicmp(szFs, L"FAT16") ||
!wcsicmp(szFs, L"FAT")) //REACTOS HACK
{
if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024))
ClusterSize = 2048;
else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024))
ClusterSize = 512;
else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
ClusterSize = 1024;
else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
ClusterSize = 2048;
else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
ClusterSize = 4096;
else if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))
ClusterSize = 8192;
else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
ClusterSize = 16384;
else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
ClusterSize = 32768;
else if (TotalNumberOfBytes->QuadPart <= (4096LL * 1024LL * 1024LL))
ClusterSize = 8192;
else
return FALSE;
}
else if (!wcsicmp(szFs, L"FAT32"))
{
if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
ClusterSize = 512;
else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
ClusterSize = 1024;
else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
ClusterSize = 2048;
else if (TotalNumberOfBytes->QuadPart <= (8192LL * 1024LL * 1024LL))
ClusterSize = 2048;
else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL))
ClusterSize = 8192;
else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL))
ClusterSize = 16384;
else
return FALSE;
}
else if (!wcsicmp(szFs, L"NTFS"))
{
if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))
ClusterSize = 512;
else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
ClusterSize = 1024;
else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
ClusterSize = 2048;
else
ClusterSize = 2048;
}
else if (!wcsicmp(szFs, L"EXT2"))
{
// auto block size calculation
ClusterSize = 0;
}
else if (!wcsicmp(szFs, L"BtrFS"))
{
// auto block size calculation
ClusterSize = 0;
}
else
return FALSE;
*pClusterSize = ClusterSize;
return TRUE;
}
static BOOL CALLBACK
AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
{
PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
if (ppsh->nPages < MAX_PROPERTY_SHEET_PAGE)
{
ppsh->phpage[ppsh->nPages++] = hPage;
return TRUE;
}
return FALSE;
}
typedef struct _DRIVE_PROP_PAGE
{
LPCSTR resname;
DLGPROC dlgproc;
UINT DriveType;
} DRIVE_PROP_PAGE;
BOOL
SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
{
HPSXA hpsx = NULL;
HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];
PROPSHEETHEADERW psh;
CComObject<CDrvDefExt> *pDrvDefExt = NULL;
WCHAR wszName[256];
ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
psh.dwSize = sizeof(PROPSHEETHEADERW);
psh.dwFlags = 0; // FIXME: make it modeless
psh.hwndParent = NULL;
psh.nStartPage = 0;
psh.phpage = hpsp;
LPITEMIDLIST completePidl = ILCombine(pidlFolder, apidl[0]);
if (!completePidl)
return FALSE;
if (ILGetDisplayNameExW(NULL, completePidl, wszName, ILGDN_NORMAL))
{
psh.pszCaption = wszName;
psh.dwFlags |= PSH_PROPTITLE;
}
ILFree(completePidl);
CComPtr<IDataObject> pDataObj;
HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
if (SUCCEEDED(hr))
{
hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt);
if (SUCCEEDED(hr))
{
pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count
hr = pDrvDefExt->Initialize(pidlFolder, pDataObj, NULL);
if (SUCCEEDED(hr))
{
hr = pDrvDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh);
if (FAILED(hr))
ERR("AddPages failed\n");
} else
ERR("Initialize failed\n");
}
hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE, pDataObj);
if (hpsx)
SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh);
}
HWND hwnd = (HWND)PropertySheetW(&psh);
if (hpsx)
SHDestroyPropSheetExtArray(hpsx);
if (pDrvDefExt)
pDrvDefExt->Release();
if (!hwnd)
return FALSE;
return TRUE;
}
static VOID
InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
{
WCHAR wszBuf[100] = {0};
WCHAR szDrive[] = L"C:\\";
INT iSelIndex;
ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
DWORD ClusterSize;
LRESULT lIndex;
HWND hDlgCtrl;
hDlgCtrl = GetDlgItem(hwndDlg, 28677);
iSelIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
if (iSelIndex == CB_ERR)
return;
if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)wszBuf) == CB_ERR)
return;
szDrive[0] = pContext->Drive + L'A';
if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
return;
if (!wcsicmp(wszBuf, L"FAT16") ||
!wcsicmp(wszBuf, L"FAT")) //REACTOS HACK
{
if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("FAT16 is not supported on hdd larger than 4G current %lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
{
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
}
SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE);
}
else if (!wcsicmp(wszBuf, L"FAT32"))
{
if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("FAT32 is not supported on hdd larger than 32G current %lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
{
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
}
SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE);
}
else if (!wcsicmp(wszBuf, L"NTFS"))
{
if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("NTFS is not supported on hdd larger than 2TB current %lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
{
SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
}
ClusterSize = 512;
for (lIndex = 0; lIndex < 4; lIndex++)
{
TotalNumberOfBytes.QuadPart = ClusterSize;
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
{
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
}
ClusterSize *= 2;
}
EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
}
else if (!wcsicmp(wszBuf, L"EXT2"))
{
if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("EXT2 is not supported on hdd larger than 32T current %lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
{
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
}
EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
}
else if (!wcsicmp(wszBuf, L"BtrFS"))
{
if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("BtrFS is not supported on hdd larger than 16E current %lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
{
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
if (lIndex != CB_ERR)
SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
}
EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
}
else
{
FIXME("unknown fs\n");
SendDlgItemMessageW(hwndDlg, 28680, CB_RESETCONTENT, iSelIndex, 0);
return;
}
}
static VOID
InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
{
WCHAR szText[120];
WCHAR szDrive[] = L"C:\\";
WCHAR szFs[30] = L"";
INT cchText;
ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
DWORD dwIndex, dwDefault;
UCHAR uMinor, uMajor;
BOOLEAN Latest;
HWND hwndFileSystems;
cchText = GetWindowTextW(hwndDlg, szText, _countof(szText) - 1);
if (cchText < 0)
cchText = 0;
szText[cchText++] = L' ';
szDrive[0] = pContext->Drive + L'A';
if (GetVolumeInformationW(szDrive, &szText[cchText], _countof(szText) - cchText, NULL, NULL, NULL, szFs, _countof(szFs)))
{
if (szText[cchText] == UNICODE_NULL)
{
/* load default volume label */
cchText += LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchText], _countof(szText) - cchText);
}
else
{
/* set volume label */
SetDlgItemTextW(hwndDlg, 28679, &szText[cchText]);
cchText += wcslen(&szText[cchText]);
}
}
StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c:)", szDrive[0]);
/* set window text */
SetWindowTextW(hwndDlg, szText);
if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
{
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, _countof(szText)))
{
/* add drive capacity */
SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText);
SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0);
}
}
if (pContext->Options & SHFMT_OPT_FULL)
{
/* check quick format button */
SendDlgItemMessageW(hwndDlg, 28674, BM_SETCHECK, BST_CHECKED, 0);
}
/* enumerate all available filesystems */
dwIndex = 0;
dwDefault = 0;
hwndFileSystems = GetDlgItem(hwndDlg, 28677);
while(QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest))
{
if (!wcsicmp(szText, szFs))
dwDefault = dwIndex;
SendMessageW(hwndFileSystems, CB_ADDSTRING, 0, (LPARAM)szText);
dwIndex++;
}
if (!dwIndex)
{
ERR("no filesystem providers\n");
return;
}
/* select default filesys */
SendMessageW(hwndFileSystems, CB_SETCURSEL, dwDefault, 0);
/* setup cluster combo */
InsertDefaultClusterSizeForFs(hwndDlg, pContext);
/* hide progress control */
ShowWindow(GetDlgItem(hwndDlg, 28678), SW_HIDE);
}
static HWND FormatDrvDialog = NULL;
static BOOLEAN bSuccess = FALSE;
static BOOLEAN NTAPI
FormatExCB(
IN CALLBACKCOMMAND Command,
IN ULONG SubAction,
IN PVOID ActionInfo)
{
PDWORD Progress;
PBOOLEAN pSuccess;
switch(Command)
{
case PROGRESS:
Progress = (PDWORD)ActionInfo;
SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0);
break;
case DONE:
pSuccess = (PBOOLEAN)ActionInfo;
bSuccess = (*pSuccess);
break;
case VOLUMEINUSE:
case INSUFFICIENTRIGHTS:
case FSNOTSUPPORTED:
case CLUSTERSIZETOOSMALL:
bSuccess = FALSE;
FIXME("\n");
break;
default:
break;
}
return TRUE;
}
VOID
FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
{
WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
WCHAR szFileSys[40] = {0};
WCHAR szLabel[40] = {0};
INT iSelIndex;
UINT Length;
HWND hDlgCtrl;
BOOL QuickFormat;
DWORD ClusterSize;
DWORD DriveType;
FMIFS_MEDIA_FLAG MediaFlag = FMIFS_HARDDISK;
/* set volume path */
szDrive[0] = pContext->Drive + L'A';
/* get filesystem */
hDlgCtrl = GetDlgItem(hwndDlg, 28677);
iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
if (iSelIndex == CB_ERR)
{
FIXME("\n");
return;
}
Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0);
if ((int)Length == CB_ERR || Length + 1 > _countof(szFileSys))
{
FIXME("\n");
return;
}
/* retrieve the file system */
SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys);
szFileSys[_countof(szFileSys)-1] = L'\0';
/* retrieve the volume label */
hDlgCtrl = GetWindow(hwndDlg, 28679);
Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0);
if (Length + 1 > _countof(szLabel))
{
FIXME("\n");
return;
}
SendMessageW(hDlgCtrl, WM_GETTEXT, _countof(szLabel), (LPARAM)szLabel);
szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0';
/* check for quickformat */
if (SendDlgItemMessageW(hwndDlg, 28674, BM_GETCHECK, 0, 0) == BST_CHECKED)
QuickFormat = TRUE;
else
QuickFormat = FALSE;
/* get the cluster size */
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
if (iSelIndex == CB_ERR)
{
FIXME("\n");
return;
}
ClusterSize = SendMessageW(hDlgCtrl, CB_GETITEMDATA, iSelIndex, 0);
if ((int)ClusterSize == CB_ERR)
{
FIXME("\n");
return;
}
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
ShowWindow(hDlgCtrl, SW_SHOW);
SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
bSuccess = FALSE;
/* FIXME
* will cause display problems
* when performing more than one format
*/
FormatDrvDialog = hwndDlg;
/* See if the drive is removable or not */
DriveType = GetDriveTypeW(szDrive);
switch (DriveType)
{
case DRIVE_UNKNOWN:
case DRIVE_REMOTE:
case DRIVE_CDROM:
case DRIVE_NO_ROOT_DIR:
{
FIXME("\n");
return;
}
case DRIVE_REMOVABLE:
MediaFlag = FMIFS_FLOPPY;
break;
case DRIVE_FIXED:
case DRIVE_RAMDISK:
MediaFlag = FMIFS_HARDDISK;
break;
}
/* Format the drive */
FormatEx(szDrive,
MediaFlag,
szFileSys,
szLabel,
QuickFormat,
ClusterSize,
FormatExCB);
ShowWindow(hDlgCtrl, SW_HIDE);
FormatDrvDialog = NULL;
if (!bSuccess)
{
pContext->Result = SHFMT_ERROR;
}
else if (QuickFormat)
{
pContext->Result = SHFMT_OPT_FULL;
}
else
{
pContext->Result = FALSE;
}
}
static INT_PTR CALLBACK
FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PFORMAT_DRIVE_CONTEXT pContext;
switch(uMsg)
{
case WM_INITDIALOG:
InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
FormatDrive(hwndDlg, pContext);
break;
case IDCANCEL:
pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
EndDialog(hwndDlg, pContext->Result);
break;
case 28677: // filesystem combo
if (HIWORD(wParam) == CBN_SELENDOK)
{
pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
InsertDefaultClusterSizeForFs(hwndDlg, pContext);
}
break;
}
}
return FALSE;
}
/*************************************************************************
* SHFormatDrive (SHELL32.@)
*/
DWORD
WINAPI
SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
{
FORMAT_DRIVE_CONTEXT Context;
int result;
TRACE("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options);
Context.Drive = drive;
Context.Options = options;
result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_FORMAT_DRIVE), hwnd, FormatDriveDlg, (LPARAM)&Context);
return result;
}

View file

@ -0,0 +1,680 @@
/*
* Provides default drive shell extension
*
* Copyright 2005 Johannes Anderwald
* Copyright 2012 Rafal Harabien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#define _USE_MATH_DEFINES
#include <math.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
typedef enum
{
HWPD_STANDARDLIST = 0,
HWPD_LARGELIST,
HWPD_MAX = HWPD_LARGELIST
} HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;
EXTERN_C HWND WINAPI
DeviceCreateHardwarePageEx(HWND hWndParent,
LPGUID lpGuids,
UINT uNumberOfGuids,
HWPAGE_DISPLAYMODE DisplayMode);
UINT SH_FormatByteSize(LONGLONG cbSize, LPWSTR pwszResult, UINT cchResultMax);
static VOID
GetDriveNameWithLetter(LPWSTR pwszText, UINT cchTextMax, LPCWSTR pwszDrive)
{
DWORD dwMaxComp, dwFileSys;
SIZE_T cchText = 0;
if (GetVolumeInformationW(pwszDrive, pwszText, cchTextMax, NULL, &dwMaxComp, &dwFileSys, NULL, 0))
{
cchText = wcslen(pwszText);
if (cchText == 0)
{
/* load default volume label */
cchText = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, pwszText, cchTextMax);
}
}
StringCchPrintfW(pwszText + cchText, cchTextMax - cchText, L" (%c:)", pwszDrive[0]);
}
static VOID
InitializeChkDskDialog(HWND hwndDlg, LPCWSTR pwszDrive)
{
WCHAR wszText[100];
UINT Length;
SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pwszDrive);
Length = GetWindowTextW(hwndDlg, wszText, sizeof(wszText) / sizeof(WCHAR));
wszText[Length] = L' ';
GetDriveNameWithLetter(&wszText[Length + 1], (sizeof(wszText) / sizeof(WCHAR)) - Length - 1, pwszDrive);
SetWindowText(hwndDlg, wszText);
}
static HWND hChkdskDrvDialog = NULL;
static BOOLEAN bChkdskSuccess = FALSE;
static BOOLEAN NTAPI
ChkdskCallback(
IN CALLBACKCOMMAND Command,
IN ULONG SubAction,
IN PVOID ActionInfo)
{
PDWORD Progress;
PBOOLEAN pSuccess;
switch(Command)
{
case PROGRESS:
Progress = (PDWORD)ActionInfo;
SendDlgItemMessageW(hChkdskDrvDialog, 14002, PBM_SETPOS, (WPARAM)*Progress, 0);
break;
case DONE:
pSuccess = (PBOOLEAN)ActionInfo;
bChkdskSuccess = (*pSuccess);
break;
case VOLUMEINUSE:
case INSUFFICIENTRIGHTS:
case FSNOTSUPPORTED:
case CLUSTERSIZETOOSMALL:
bChkdskSuccess = FALSE;
FIXME("\n");
break;
default:
break;
}
return TRUE;
}
static VOID
ChkDskNow(HWND hwndDlg, LPCWSTR pwszDrive)
{
//DWORD ClusterSize = 0;
WCHAR wszFs[30];
ULARGE_INTEGER TotalNumberOfFreeBytes, FreeBytesAvailableUser;
BOOLEAN bCorrectErrors = FALSE, bScanDrive = FALSE;
if(!GetVolumeInformationW(pwszDrive, NULL, 0, NULL, NULL, NULL, wszFs, _countof(wszFs)))
{
FIXME("failed to get drive fs type\n");
return;
}
if (!GetDiskFreeSpaceExW(pwszDrive, &FreeBytesAvailableUser, &TotalNumberOfFreeBytes, NULL))
{
FIXME("failed to get drive space type\n");
return;
}
/*if (!GetDefaultClusterSize(wszFs, &ClusterSize, &TotalNumberOfFreeBytes))
{
FIXME("invalid cluster size\n");
return;
}*/
if (SendDlgItemMessageW(hwndDlg, 14000, BM_GETCHECK, 0, 0) == BST_CHECKED)
bCorrectErrors = TRUE;
if (SendDlgItemMessageW(hwndDlg, 14001, BM_GETCHECK, 0, 0) == BST_CHECKED)
bScanDrive = TRUE;
hChkdskDrvDialog = hwndDlg;
bChkdskSuccess = FALSE;
SendDlgItemMessageW(hwndDlg, 14002, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
Chkdsk((LPWSTR)pwszDrive, (LPWSTR)wszFs, bCorrectErrors, TRUE, FALSE, bScanDrive, NULL, NULL, ChkdskCallback); // FIXME: casts
hChkdskDrvDialog = NULL;
bChkdskSuccess = FALSE;
}
static INT_PTR CALLBACK
ChkDskDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
InitializeChkDskDialog(hwndDlg, (LPCWSTR)lParam);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hwndDlg, 0);
break;
case IDOK:
{
LPCWSTR pwszDrive = (LPCWSTR)GetWindowLongPtr(hwndDlg, DWLP_USER);
ChkDskNow(hwndDlg, pwszDrive);
break;
}
}
break;
}
return FALSE;
}
VOID
CDrvDefExt::PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT pDrawItem)
{
HBRUSH hBrush;
if (pDrawItem->CtlID == 14013)
{
hBrush = CreateSolidBrush(RGB(0, 0, 255));
if (hBrush)
{
FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush);
DeleteObject((HGDIOBJ)hBrush);
}
}
else if (pDrawItem->CtlID == 14014)
{
hBrush = CreateSolidBrush(RGB(255, 0, 255));
if (hBrush)
{
FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush);
DeleteObject((HGDIOBJ)hBrush);
}
}
else if (pDrawItem->CtlID == 14015)
{
HBRUSH hBlueBrush = CreateSolidBrush(RGB(0, 0, 255));
HBRUSH hMagBrush = CreateSolidBrush(RGB(255, 0, 255));
HBRUSH hbrOld;
HPEN hDarkBluePen = CreatePen(PS_SOLID, 1, RGB(0, 0, 128));
HPEN hDarkMagPen = CreatePen(PS_SOLID, 1, RGB(128, 0, 128));
HPEN hOldPen = (HPEN)SelectObject(pDrawItem->hDC, hDarkMagPen);
INT xCenter = (pDrawItem->rcItem.left + pDrawItem->rcItem.right) / 2;
INT yCenter = (pDrawItem->rcItem.top + pDrawItem->rcItem.bottom - 10) / 2;
INT cx = pDrawItem->rcItem.right - pDrawItem->rcItem.left;
INT cy = pDrawItem->rcItem.bottom - pDrawItem->rcItem.top - 10;
INT xRadial = xCenter + (INT)(cos(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cx / 2);
INT yRadial = yCenter - (INT)(sin(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cy / 2);
TRACE("FreeSpace %u a %f cx %d\n", m_FreeSpacePerc, M_PI+m_FreeSpacePerc / 100.0f * M_PI * 2.0f, cx);
for (INT x = pDrawItem->rcItem.left; x < pDrawItem->rcItem.right; ++x)
{
double cos_val = (x - xCenter) * 2.0f / cx;
INT y = yCenter + (INT)(sin(acos(cos_val)) * cy / 2) - 1;
if (m_FreeSpacePerc < 50 && x == xRadial)
SelectObject(pDrawItem->hDC, hDarkBluePen);
MoveToEx(pDrawItem->hDC, x, y, NULL);
LineTo(pDrawItem->hDC, x, y + 10);
}
SelectObject(pDrawItem->hDC, hOldPen);
if (m_FreeSpacePerc > 50)
{
hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hMagBrush);
Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top,
pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
SelectObject(pDrawItem->hDC, hBlueBrush);
if (m_FreeSpacePerc < 100)
{
Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right,
pDrawItem->rcItem.bottom - 10, xRadial, yRadial, pDrawItem->rcItem.left, yCenter);
}
}
else
{
hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hBlueBrush);
Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top,
pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
SelectObject(pDrawItem->hDC, hMagBrush);
if (m_FreeSpacePerc > 0)
{
Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right,
pDrawItem->rcItem.bottom - 10, pDrawItem->rcItem.left, yCenter, xRadial, yRadial);
}
}
SelectObject(pDrawItem->hDC, hbrOld);
DeleteObject(hBlueBrush);
DeleteObject(hMagBrush);
DeleteObject(hDarkBluePen);
DeleteObject(hDarkMagPen);
}
}
VOID
CDrvDefExt::InitGeneralPage(HWND hwndDlg)
{
WCHAR wszVolumeName[MAX_PATH+1] = {0};
WCHAR wszFileSystem[MAX_PATH+1] = {0};
WCHAR wszBuf[128];
BOOL bRet;
bRet = GetVolumeInformationW(m_wszDrive, wszVolumeName, _countof(wszVolumeName), NULL, NULL, NULL, wszFileSystem, _countof(wszFileSystem));
if (bRet)
{
/* Set volume label and filesystem */
SetDlgItemTextW(hwndDlg, 14000, wszVolumeName);
SetDlgItemTextW(hwndDlg, 14002, wszFileSystem);
}
else
{
LoadStringW(shell32_hInstance, IDS_FS_UNKNOWN, wszFileSystem, _countof(wszFileSystem));
SetDlgItemTextW(hwndDlg, 14002, wszFileSystem);
}
/* Set drive type and icon */
UINT DriveType = GetDriveTypeW(m_wszDrive);
UINT IconId, TypeStrId = 0;
switch (DriveType)
{
case DRIVE_REMOVABLE: IconId = IDI_SHELL_3_14_FLOPPY; break;
case DRIVE_CDROM: IconId = IDI_SHELL_CDROM; TypeStrId = IDS_DRIVE_CDROM; break;
case DRIVE_REMOTE: IconId = IDI_SHELL_NETDRIVE; TypeStrId = IDS_DRIVE_NETWORK; break;
case DRIVE_RAMDISK: IconId = IDI_SHELL_RAMDISK; break;
default: IconId = IDI_SHELL_DRIVE; TypeStrId = IDS_DRIVE_FIXED;
}
if (DriveType == DRIVE_CDROM || DriveType == DRIVE_REMOTE)
{
/* volume label textbox */
SendMessage(GetDlgItem(hwndDlg, 14000), EM_SETREADONLY, TRUE, 0);
/* disk compression */
ShowWindow(GetDlgItem(hwndDlg, 14011), FALSE);
/* index */
ShowWindow(GetDlgItem(hwndDlg, 14012), FALSE);
}
HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IconId), IMAGE_ICON, 32, 32, LR_SHARED);
if (hIcon)
SendDlgItemMessageW(hwndDlg, 14016, STM_SETICON, (WPARAM)hIcon, 0);
if (TypeStrId && LoadStringW(shell32_hInstance, TypeStrId, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14001, wszBuf);
ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes;
if(GetDiskFreeSpaceExW(m_wszDrive, &FreeBytesAvailable, &TotalNumberOfBytes, NULL))
{
/* Init free space percentage used for drawing piechart */
m_FreeSpacePerc = (UINT)(FreeBytesAvailable.QuadPart * 100ull / TotalNumberOfBytes.QuadPart);
/* Used space */
if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14003, wszBuf);
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14004, wszBuf);
/* Free space */
if (SH_FormatByteSize(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14005, wszBuf);
if (StrFormatByteSizeW(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14006, wszBuf);
/* Total space */
if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14007, wszBuf);
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
SetDlgItemTextW(hwndDlg, 14008, wszBuf);
}
else
{
m_FreeSpacePerc = 0;
if (SH_FormatByteSize(0, wszBuf, _countof(wszBuf)))
{
SetDlgItemTextW(hwndDlg, 14003, wszBuf);
SetDlgItemTextW(hwndDlg, 14005, wszBuf);
SetDlgItemTextW(hwndDlg, 14007, wszBuf);
}
if (StrFormatByteSizeW(0, wszBuf, _countof(wszBuf)))
{
SetDlgItemTextW(hwndDlg, 14004, wszBuf);
SetDlgItemTextW(hwndDlg, 14006, wszBuf);
SetDlgItemTextW(hwndDlg, 14008, wszBuf);
}
}
/* Set drive description */
WCHAR wszFormat[50];
GetDlgItemTextW(hwndDlg, 14009, wszFormat, _countof(wszFormat));
swprintf(wszBuf, wszFormat, m_wszDrive[0]);
SetDlgItemTextW(hwndDlg, 14009, wszBuf);
/* show disk cleanup button only for fixed drives */
ShowWindow(GetDlgItem(hwndDlg, 14010), DriveType == DRIVE_FIXED);
}
INT_PTR CALLBACK
CDrvDefExt::GeneralPageProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
if (ppsp == NULL)
break;
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(ppsp->lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pDrvDefExt);
pDrvDefExt->InitGeneralPage(hwndDlg);
return TRUE;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT pDrawItem = (LPDRAWITEMSTRUCT)lParam;
if (pDrawItem->CtlID >= 14013 && pDrawItem->CtlID <= 14015)
{
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
pDrvDefExt->PaintStaticControls(hwndDlg, pDrawItem);
return TRUE;
}
break;
}
case WM_PAINT:
break;
case WM_COMMAND:
if (LOWORD(wParam) == 14010) /* Disk Cleanup */
{
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
WCHAR wszBuf[256];
DWORD cbBuf = sizeof(wszBuf);
if (RegGetValueW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\CleanupPath",
NULL,
RRF_RT_REG_SZ,
NULL,
(PVOID)wszBuf,
&cbBuf) == ERROR_SUCCESS)
{
WCHAR wszCmd[MAX_PATH];
StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]);
if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
ERR("Failed to create cleanup process %ls\n", wszCmd);
}
}
else if (LOWORD(wParam) == 14000) /* Label */
{
if (HIWORD(wParam) == EN_CHANGE)
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case WM_NOTIFY:
if (((LPNMHDR)lParam)->hwndFrom == GetParent(hwndDlg))
{
/* Property Sheet */
LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
if (lppsn->hdr.code == PSN_APPLY)
{
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
WCHAR wszBuf[256];
if (GetDlgItemTextW(hwndDlg, 14000, wszBuf, _countof(wszBuf)))
SetVolumeLabelW(pDrvDefExt->m_wszDrive, wszBuf);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
return TRUE;
}
}
break;
default:
break;
}
return FALSE;
}
INT_PTR CALLBACK
CDrvDefExt::ExtraPageProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)ppsp->lParam);
return TRUE;
}
case WM_COMMAND:
{
WCHAR wszBuf[MAX_PATH];
DWORD cbBuf = sizeof(wszBuf);
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
switch(LOWORD(wParam))
{
case 14000:
DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_CHECK_DISK), hwndDlg, ChkDskDlg, (LPARAM)pDrvDefExt->m_wszDrive);
break;
case 14001:
if (RegGetValueW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\DefragPath",
NULL,
RRF_RT_REG_SZ,
NULL,
(PVOID)wszBuf,
&cbBuf) == ERROR_SUCCESS)
{
WCHAR wszCmd[MAX_PATH];
StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]);
if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
ERR("Failed to create defrag process %ls\n", wszCmd);
}
break;
case 14002:
if (RegGetValueW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\BackupPath",
NULL,
RRF_RT_REG_SZ,
NULL,
(PVOID)wszBuf,
&cbBuf) == ERROR_SUCCESS)
{
if (ShellExecuteW(hwndDlg, NULL, wszBuf, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
ERR("Failed to create backup process %ls\n", wszBuf);
}
}
break;
}
}
return FALSE;
}
INT_PTR CALLBACK
CDrvDefExt::HardwarePageProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
switch(uMsg)
{
case WM_INITDIALOG:
{
GUID Guid = GUID_DEVCLASS_DISKDRIVE;
/* create the hardware page */
DeviceCreateHardwarePageEx(hwndDlg, &Guid, 1, HWPD_STANDARDLIST);
break;
}
}
return FALSE;
}
CDrvDefExt::CDrvDefExt()
{
m_wszDrive[0] = L'\0';
}
CDrvDefExt::~CDrvDefExt()
{
}
HRESULT WINAPI
CDrvDefExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID)
{
FORMATETC format;
STGMEDIUM stgm;
HRESULT hr;
TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID);
if (!pDataObj)
return E_FAIL;
format.cfFormat = CF_HDROP;
format.ptd = NULL;
format.dwAspect = DVASPECT_CONTENT;
format.lindex = -1;
format.tymed = TYMED_HGLOBAL;
hr = pDataObj->GetData(&format, &stgm);
if (FAILED(hr))
return hr;
if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszDrive, _countof(m_wszDrive)))
{
ERR("DragQueryFileW failed\n");
ReleaseStgMedium(&stgm);
return E_FAIL;
}
ReleaseStgMedium(&stgm);
TRACE("Drive properties %ls\n", m_wszDrive);
return S_OK;
}
HRESULT WINAPI
CDrvDefExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI
CDrvDefExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI
CDrvDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI
CDrvDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam)
{
HPROPSHEETPAGE hPage;
hPage = SH_CreatePropertySheetPage(IDD_DRIVE_PROPERTIES,
GeneralPageProc,
(LPARAM)this,
NULL);
if (hPage)
pfnAddPage(hPage, lParam);
if (GetDriveTypeW(m_wszDrive) == DRIVE_FIXED)
{
hPage = SH_CreatePropertySheetPage(IDD_DRIVE_TOOLS,
ExtraPageProc,
(LPARAM)this,
NULL);
if (hPage)
pfnAddPage(hPage, lParam);
}
hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE,
HardwarePageProc,
(LPARAM)this,
NULL);
if (hPage)
pfnAddPage(hPage, lParam);
return S_OK;
}
HRESULT WINAPI
CDrvDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI
CDrvDefExt::SetSite(IUnknown *punk)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI
CDrvDefExt::GetSite(REFIID iid, void **ppvSite)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}

View file

@ -0,0 +1,75 @@
/*
* Provides default drive shell extension
*
* Copyright 2012 Rafal Harabien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _DRV_DEF_EXT_H_
#define _DRV_DEF_EXT_H_
class CDrvDefExt :
public CComCoClass<CDrvDefExt, &CLSID_ShellDrvDefExt>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellExtInit,
public IContextMenu,
public IShellPropSheetExt,
public IObjectWithSite
{
private:
VOID PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT pDrawItem);
VOID InitGeneralPage(HWND hwndDlg);
static INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK ExtraPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
WCHAR m_wszDrive[MAX_PATH];
UINT m_FreeSpacePerc;
public:
CDrvDefExt();
~CDrvDefExt();
// IShellExtInit
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
// IShellPropSheetExt
virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
// IObjectWithSite
virtual HRESULT WINAPI SetSite(IUnknown *punk);
virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
DECLARE_REGISTRY_RESOURCEID(IDR_DRVDEFEXT)
DECLARE_NOT_AGGREGATABLE(CDrvDefExt)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDrvDefExt)
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
END_COM_MAP()
};
#endif /* _DRV_DEF_EXT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,128 @@
/*
* Provides default file shell extension
*
* Copyright 2012 Rafal Harabien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _FILE_DEF_EXT_H_
#define _FILE_DEF_EXT_H_
class CFileVersionInfo
{
private:
PVOID m_pInfo;
WORD m_wLang, m_wCode;
WCHAR m_wszLang[64];
typedef struct _LANGANDCODEPAGE_
{
WORD wLang;
WORD wCode;
} LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
public:
inline CFileVersionInfo():
m_pInfo(NULL), m_wLang(0), m_wCode(0)
{
m_wszLang[0] = L'\0';
}
inline ~CFileVersionInfo()
{
if (m_pInfo)
HeapFree(GetProcessHeap(), 0, m_pInfo);
}
BOOL Load(LPCWSTR pwszPath);
LPCWSTR GetString(LPCWSTR pwszName);
VS_FIXEDFILEINFO *GetFixedInfo();
LPCWSTR GetLangName();
};
class CFileDefExt :
public CComCoClass<CFileDefExt, &CLSID_ShellFileDefExt>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellExtInit,
public IContextMenu,
public IShellPropSheetExt,
public IObjectWithSite
{
private:
VOID InitOpensWithField(HWND hwndDlg);
BOOL InitFileType(HWND hwndDlg);
BOOL InitFilePath(HWND hwndDlg);
static BOOL GetFileTimeString(LPFILETIME lpFileTime, LPWSTR pwszResult, UINT cchResult);
BOOL InitFileAttr(HWND hwndDlg);
BOOL InitGeneralPage(HWND hwndDlg);
BOOL SetVersionLabel(HWND hwndDlg, DWORD idCtrl, LPCWSTR pwszName);
BOOL AddVersionString(HWND hwndDlg, LPCWSTR pwszName);
BOOL InitVersionPage(HWND hwndDlg);
static INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, LPDWORD ticks);
WCHAR m_wszPath[MAX_PATH];
CFileVersionInfo m_VerInfo;
BOOL m_bDir;
DWORD m_cFiles;
DWORD m_cFolders;
ULARGE_INTEGER m_DirSize;
static DWORD WINAPI _CountFolderAndFilesThreadProc(LPVOID lpParameter);
public:
CFileDefExt();
~CFileDefExt();
// IShellExtInit
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
// IShellPropSheetExt
virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
// IObjectWithSite
virtual HRESULT WINAPI SetSite(IUnknown *punk);
virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
DECLARE_REGISTRY_RESOURCEID(IDR_FILEDEFEXT)
DECLARE_NOT_AGGREGATABLE(CFileDefExt)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CFileDefExt)
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
END_COM_MAP()
};
struct _CountFolderAndFilesData {
CFileDefExt *This;
HWND hwndDlg;
LPWSTR pwszBuf;
UINT cchBufMax;
};
#endif /* _FILE_DEF_EXT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,163 @@
/*
* Shell Library Functions
*
* Copyright 2005 Johannes Anderwald
* Copyright 2012 Rafal Harabien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
#define MAX_PROPERTY_SHEET_PAGE 32
WINE_DEFAULT_DEBUG_CHANNEL(shell);
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
static BOOL CALLBACK
AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
{
PROPSHEETHEADERW *pHeader = (PROPSHEETHEADERW *)lParam;
if (pHeader->nPages < MAX_PROPERTY_SHEET_PAGE)
{
pHeader->phpage[pHeader->nPages++] = hPage;
return TRUE;
}
return FALSE;
}
static UINT
LoadPropSheetHandlers(LPCWSTR pwszPath, PROPSHEETHEADERW *pHeader, UINT cMaxPages, HPSXA *phpsxa, IDataObject *pDataObj)
{
WCHAR wszBuf[MAX_PATH];
UINT cPages = 0, i = 0;
LPWSTR pwszFilename = PathFindFileNameW(pwszPath);
BOOL bDir = PathIsDirectoryW(pwszPath);
if (bDir)
{
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Folder", cMaxPages - cPages, pDataObj);
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Directory", cMaxPages - cPages, pDataObj);
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
}
else
{
/* Load property sheet handlers from ext key */
LPWSTR pwszExt = PathFindExtensionW(pwszFilename);
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, pwszExt, cMaxPages - cPages, pDataObj);
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
/* Load property sheet handlers from prog id key */
DWORD cbBuf = sizeof(wszBuf);
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS)
{
TRACE("EnumPropSheetExt wszBuf %s, pwszExt %s\n", debugstr_w(wszBuf), debugstr_w(pwszExt));
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszBuf, cMaxPages - cPages, pDataObj);
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
}
/* Add property sheet handlers from "*" key */
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"*", cMaxPages - cPages, pDataObj);
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
}
return cPages;
}
/*************************************************************************
*
* SH_ShowPropertiesDialog
*
* called from ShellExecuteExW32
*
* pwszPath contains path of folder/file
*
* TODO: provide button change application type if file has registered type
* make filename field editable and apply changes to filename on close
*/
BOOL
SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
{
HPSXA hpsxa[3] = {NULL, NULL, NULL};
CComObject<CFileDefExt> *pFileDefExt = NULL;
TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(pwszPath));
if (pwszPath == NULL || !wcslen(pwszPath))
return FALSE;
HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
/* Make a copy of path */
WCHAR wszPath[MAX_PATH];
StringCbCopyW(wszPath, sizeof(wszPath), pwszPath);
/* remove trailing \\ at the end of path */
PathRemoveBackslashW(wszPath);
/* Handle drives */
if (PathIsRootW(wszPath))
return SH_ShowDriveProperties(wszPath, pidlFolder, apidl);
/* Handle files and folders */
PROPSHEETHEADERW Header;
memset(&Header, 0x0, sizeof(PROPSHEETHEADERW));
Header.dwSize = sizeof(PROPSHEETHEADERW);
Header.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
Header.phpage = hppages;
Header.pszCaption = PathFindFileNameW(wszPath);
CComPtr<IDataObject> pDataObj;
HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
if (SUCCEEDED(hr))
{
hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt);
if (SUCCEEDED(hr))
{
pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count
hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL);
if (SUCCEEDED(hr))
{
hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header);
if (FAILED(hr))
ERR("AddPages failed\n");
} else
ERR("Initialize failed\n");
}
LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj);
}
INT_PTR Result = PropertySheetW(&Header);
for (UINT i = 0; i < 3; ++i)
if (hpsxa[i])
SHDestroyPropSheetExtArray(hpsxa[i]);
if (pFileDefExt)
pFileDefExt->Release();
return (Result != -1);
}
/*EOF */

View file

@ -0,0 +1,413 @@
/*
* Trash virtual folder support. The trashing engine is implemented in trash.c
*
* Copyright (C) 2006 Mikolaj Zalewski
* Copyright (C) 2009 Andrew Hill
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(CRecycleBin);
typedef struct
{
DWORD dwNukeOnDelete;
DWORD dwSerial;
DWORD dwMaxCapacity;
} DRIVE_ITEM_CONTEXT, *PDRIVE_ITEM_CONTEXT;
static void toggleNukeOnDeleteOption(HWND hwndDlg, BOOL bEnable)
{
if (bEnable)
{
SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE);
SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_CHECKED, 0);
}
else
{
SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_CHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, 14002), TRUE);
SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_UNCHECKED, 0);
}
}
static VOID
InitializeRecycleBinDlg(HWND hwndDlg, WCHAR DefaultDrive)
{
WCHAR CurDrive = L'A';
WCHAR szDrive[] = L"A:\\";
DWORD dwDrives;
WCHAR szName[100];
WCHAR szVolume[100];
DWORD MaxComponent, Flags;
DWORD dwSerial;
LVCOLUMNW lc;
HWND hDlgCtrl;
LVITEMW li;
INT itemCount;
ULARGE_INTEGER TotalNumberOfFreeBytes, TotalNumberOfBytes, FreeBytesAvailable;
RECT rect;
int columnSize;
int defIndex = 0;
DWORD dwSize;
PDRIVE_ITEM_CONTEXT pItem = NULL, pDefault = NULL, pFirst = NULL;
hDlgCtrl = GetDlgItem(hwndDlg, 14000);
if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_LOCATION, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
szVolume[0] = 0;
GetClientRect(hDlgCtrl, &rect);
memset(&lc, 0, sizeof(LV_COLUMN) );
lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
columnSize = 140; //FIXME
lc.iSubItem = 0;
lc.fmt = LVCFMT_FIXED_WIDTH;
lc.cx = columnSize;
lc.cchTextMax = wcslen(szVolume);
lc.pszText = szVolume;
(void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&lc);
if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_DISKSPACE, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
szVolume[0] = 0;
lc.iSubItem = 1;
lc.cx = rect.right - rect.left - columnSize;
lc.cchTextMax = wcslen(szVolume);
lc.pszText = szVolume;
(void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&lc);
dwDrives = GetLogicalDrives();
itemCount = 0;
do
{
if ((dwDrives & 0x1))
{
UINT Type = GetDriveTypeW(szDrive);
if (Type == DRIVE_FIXED) //FIXME
{
if (!GetVolumeInformationW(szDrive, szName, sizeof(szName) / sizeof(WCHAR), &dwSerial, &MaxComponent, &Flags, NULL, 0))
{
szName[0] = 0;
dwSerial = -1;
}
swprintf(szVolume, L"%s (%c:)", szName, szDrive[0]);
memset(&li, 0x0, sizeof(LVITEMW));
li.mask = LVIF_TEXT | LVIF_PARAM;
li.iSubItem = 0;
li.pszText = szVolume;
li.iItem = itemCount;
SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailable , &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
{
if (StrFormatByteSizeW(TotalNumberOfFreeBytes.QuadPart, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
{
pItem = (DRIVE_ITEM_CONTEXT *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DRIVE_ITEM_CONTEXT));
if (pItem)
{
swprintf(szName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\%04X-%04X", LOWORD(dwSerial), HIWORD(dwSerial));
dwSize = sizeof(DWORD);
RegGetValueW(HKEY_CURRENT_USER, szName, L"MaxCapacity", RRF_RT_DWORD, NULL, &pItem->dwMaxCapacity, &dwSize);
dwSize = sizeof(DWORD);
RegGetValueW(HKEY_CURRENT_USER, szName, L"NukeOnDelete", RRF_RT_DWORD, NULL, &pItem->dwNukeOnDelete, &dwSize);
pItem->dwSerial = dwSerial;
li.mask = LVIF_PARAM;
li.lParam = (LPARAM)pItem;
(void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
if (CurDrive == DefaultDrive)
{
defIndex = itemCount;
pDefault = pItem;
}
}
if (!pFirst)
pFirst = pItem;
li.mask = LVIF_TEXT;
li.iSubItem = 1;
li.pszText = szVolume;
li.iItem = itemCount;
(void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
}
}
itemCount++;
}
}
CurDrive++;
szDrive[0] = CurDrive;
dwDrives = (dwDrives >> 1);
} while(dwDrives);
if (!pDefault)
pDefault = pFirst;
if (pDefault)
{
toggleNukeOnDeleteOption(hwndDlg, pDefault->dwNukeOnDelete);
SetDlgItemInt(hwndDlg, 14002, pDefault->dwMaxCapacity, FALSE);
}
ZeroMemory(&li, sizeof(li));
li.mask = LVIF_STATE;
li.stateMask = (UINT) - 1;
li.state = LVIS_FOCUSED | LVIS_SELECTED;
li.iItem = defIndex;
(void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
}
static BOOL StoreDriveSettings(HWND hwndDlg)
{
int iCount, iIndex;
HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
LVITEMW li;
PDRIVE_ITEM_CONTEXT pItem;
HKEY hKey, hSubKey;
WCHAR szSerial[20];
DWORD dwSize;
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
return FALSE;
iCount = ListView_GetItemCount(hDlgCtrl);
ZeroMemory(&li, sizeof(li));
li.mask = LVIF_PARAM;
for(iIndex = 0; iIndex < iCount; iIndex++)
{
li.iItem = iIndex;
if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
{
pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
swprintf(szSerial, L"%04X-%04X", LOWORD(pItem->dwSerial), HIWORD(pItem->dwSerial));
if (RegCreateKeyExW(hKey, szSerial, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
{
dwSize = sizeof(DWORD);
RegSetValueExW(hSubKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&pItem->dwNukeOnDelete, dwSize);
dwSize = sizeof(DWORD);
RegSetValueExW(hSubKey, L"MaxCapacity", 0, REG_DWORD, (LPBYTE)&pItem->dwMaxCapacity, dwSize);
RegCloseKey(hSubKey);
}
}
}
RegCloseKey(hKey);
return TRUE;
}
static VOID FreeDriveItemContext(HWND hwndDlg)
{
int iCount, iIndex;
HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
LVITEMW li;
iCount = ListView_GetItemCount(hDlgCtrl);
ZeroMemory(&li, sizeof(li));
li.mask = LVIF_PARAM;
for(iIndex = 0; iIndex < iCount; iIndex++)
{
li.iItem = iIndex;
if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
{
HeapFree(GetProcessHeap(), 0, (LPVOID)li.lParam);
}
}
}
static INT
GetDefaultItem(HWND hwndDlg, LVITEMW * li)
{
HWND hDlgCtrl;
UINT iItemCount, iIndex;
hDlgCtrl = GetDlgItem(hwndDlg, 14000);
if (!hDlgCtrl)
return -1;
iItemCount = ListView_GetItemCount(hDlgCtrl);
if (!iItemCount)
return -1;
ZeroMemory(li, sizeof(LVITEMW));
li->mask = LVIF_PARAM | LVIF_STATE;
li->stateMask = (UINT) - 1;
for (iIndex = 0; iIndex < iItemCount; iIndex++)
{
li->iItem = iIndex;
if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)li))
{
if (li->state & LVIS_SELECTED)
return iIndex;
}
}
return -1;
}
static INT_PTR CALLBACK
RecycleBinDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
LPPSHNOTIFY lppsn;
LPNMLISTVIEW lppl;
LVITEMW li;
PDRIVE_ITEM_CONTEXT pItem;
BOOL bSuccess;
UINT uResult;
PROPSHEETPAGE * page;
DWORD dwStyle;
switch(uMsg)
{
case WM_INITDIALOG:
page = (PROPSHEETPAGE*)lParam;
InitializeRecycleBinDlg(hwndDlg, (WCHAR)page->lParam);
dwStyle = (DWORD) SendDlgItemMessage(hwndDlg, 14000, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
SendDlgItemMessage(hwndDlg, 14000, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
if (GetDlgCtrlID((HWND)wParam) != 14000)
{
SetFocus(GetDlgItem(hwndDlg, 14000));
return FALSE;
}
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 14001:
toggleNukeOnDeleteOption(hwndDlg, FALSE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case 14003:
toggleNukeOnDeleteOption(hwndDlg, TRUE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case 14004:
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
break;
case WM_NOTIFY:
lppsn = (LPPSHNOTIFY) lParam;
lppl = (LPNMLISTVIEW) lParam;
if (lppsn->hdr.code == PSN_APPLY)
{
if (GetDefaultItem(hwndDlg, &li) > -1)
{
pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
if (pItem)
{
uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
if (bSuccess)
pItem->dwMaxCapacity = uResult;
if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
pItem->dwNukeOnDelete = TRUE;
else
pItem->dwNukeOnDelete = FALSE;
}
}
if (StoreDriveSettings(hwndDlg))
{
SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
return TRUE;
}
}
else if (lppl->hdr.code == LVN_ITEMCHANGING)
{
ZeroMemory(&li, sizeof(li));
li.mask = LVIF_PARAM;
li.iItem = lppl->iItem;
if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&li))
return TRUE;
pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
if (!pItem)
return TRUE;
if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
{
/* new focused item */
toggleNukeOnDeleteOption(lppl->hdr.hwndFrom, pItem->dwNukeOnDelete);
SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE);
}
else if ((lppl->uOldState & LVIS_FOCUSED) && !(lppl->uNewState & LVIS_FOCUSED))
{
/* kill focus */
uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
if (bSuccess)
pItem->dwMaxCapacity = uResult;
if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
pItem->dwNukeOnDelete = TRUE;
else
pItem->dwNukeOnDelete = FALSE;
}
return TRUE;
}
break;
case WM_DESTROY:
FreeDriveItemContext(hwndDlg);
break;
}
return FALSE;
}
BOOL SH_ShowRecycleBinProperties(WCHAR sDrive)
{
HPROPSHEETPAGE hpsp[1];
PROPSHEETHEADERW psh;
HPROPSHEETPAGE hprop;
BOOL ret;
ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
psh.dwSize = sizeof(PROPSHEETHEADERW);
psh.dwFlags = PSP_DEFAULT | PSH_PROPTITLE;
psh.pszCaption = MAKEINTRESOURCEW(IDS_RECYCLEBIN_FOLDER_NAME);
psh.hwndParent = NULL;
psh.phpage = hpsp;
psh.hInstance = shell32_hInstance;
hprop = SH_CreatePropertySheetPage(IDD_RECYCLE_BIN_PROPERTIES, RecycleBinDlg, (LPARAM)sDrive, NULL);
if (!hprop)
{
ERR("Failed to create property sheet\n");
return FALSE;
}
hpsp[psh.nPages] = hprop;
psh.nPages++;
ret = PropertySheetW(&psh);
if (ret < 0)
return FALSE;
else
return TRUE;
}