2 * Shell Library Functions
4 * Copyright 2005 Johannes Anderwald
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
23 #define LARGEINT_PROTOS
24 #define LargeIntegerDivide RtlLargeIntegerDivide
25 #define ExtendedIntegerMultiply RtlExtendedIntegerMultiply
26 #define ConvertUlongToLargeInteger RtlConvertUlongToLargeInteger
27 #define LargeIntegerSubtract RtlLargeIntegerSubtract
28 #define MAX_PROPERTY_SHEET_PAGE 32
39 #include "wine/debug.h"
44 #include "shell32_main.h"
46 #include "undocshell.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
57 HWPD_STANDARDLIST
= 0,
59 HWPD_MAX
= HWPD_LARGELIST
60 } HWPAGE_DISPLAYMODE
, *PHWPAGE_DISPLAYMODE
;
63 DeviceCreateHardwarePageEx(HWND hWndParent
,
66 HWPAGE_DISPLAYMODE DisplayMode
);
68 #define DRIVE_PROPERTY_PAGES (3)
73 GetFreeBytesShare(LARGE_INTEGER TotalNumberOfFreeBytes
, LARGE_INTEGER TotalNumberOfBytes
)
75 LARGE_INTEGER Temp
, Result
, Remainder
;
77 Temp
= LargeIntegerDivide(TotalNumberOfBytes
, ConvertUlongToLargeInteger(100), &Remainder
);
78 if (Temp
.QuadPart
>= TotalNumberOfFreeBytes
.QuadPart
)
80 Result
= ConvertUlongToLargeInteger(1);
83 Result
= LargeIntegerDivide(TotalNumberOfFreeBytes
, Temp
, &Remainder
);
91 PaintStaticControls(HWND hwndDlg
, LPDRAWITEMSTRUCT drawItem
)
95 if (drawItem
->CtlID
== 14013)
97 hBrush
= CreateSolidBrush(RGB(0, 0, 255));
100 FillRect(drawItem
->hDC
, &drawItem
->rcItem
, hBrush
);
101 DeleteObject((HGDIOBJ
)hBrush
);
103 }else if (drawItem
->CtlID
== 14014)
105 hBrush
= CreateSolidBrush(RGB(255, 0, 255));
108 FillRect(drawItem
->hDC
, &drawItem
->rcItem
, hBrush
);
109 DeleteObject((HGDIOBJ
)hBrush
);
112 else if (drawItem
->CtlID
== 14015)
118 LARGE_INTEGER Result
;
121 hBlueBrush
= CreateSolidBrush(RGB(0, 0, 255));
122 hMagBrush
= CreateSolidBrush(RGB(255, 0, 255));
124 SendDlgItemMessageW(hwndDlg
, 14007, WM_GETTEXT
, 20, (LPARAM
)szBuffer
);
125 Result
.QuadPart
= _wtoi(szBuffer
);
127 CopyRect(&rect
, &drawItem
->rcItem
);
128 horzsize
= rect
.right
- rect
.left
;
129 Result
.QuadPart
= (Result
.QuadPart
* horzsize
) / 100;
131 rect
.right
= rect
.left
+ Result
.QuadPart
;
132 FillRect(drawItem
->hDC
, &rect
, hMagBrush
);
133 rect
.left
= rect
.right
;
134 rect
.right
= drawItem
->rcItem
.right
;
135 FillRect(drawItem
->hDC
, &rect
, hBlueBrush
);
136 DeleteObject(hBlueBrush
);
137 DeleteObject(hMagBrush
);
143 InitializeGeneralDriveDialog(HWND hwndDlg
, WCHAR
* szDrive
)
145 WCHAR szVolumeName
[MAX_PATH
+1] = {0};
146 DWORD MaxComponentLength
= 0;
147 DWORD FileSystemFlags
= 0;
148 WCHAR FileSystemName
[MAX_PATH
+1] = {0};
153 ULARGE_INTEGER FreeBytesAvailable
;
154 LARGE_INTEGER TotalNumberOfFreeBytes
;
155 LARGE_INTEGER TotalNumberOfBytes
;
157 ret
= GetVolumeInformationW(szDrive
, szVolumeName
, MAX_PATH
+1, NULL
, &MaxComponentLength
, &FileSystemFlags
, FileSystemName
, MAX_PATH
+1);
160 /* set volume label */
161 SendDlgItemMessageW(hwndDlg
, 14001, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szVolumeName
);
163 /* set filesystem type */
164 SendDlgItemMessageW(hwndDlg
, 14003, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)FileSystemName
);
168 DriveType
= GetDriveTypeW(szDrive
);
169 if (DriveType
== DRIVE_FIXED
)
172 if(GetDiskFreeSpaceExW(szDrive
, &FreeBytesAvailable
, (PULARGE_INTEGER
)&TotalNumberOfBytes
, (PULARGE_INTEGER
)&TotalNumberOfFreeBytes
))
175 LARGE_INTEGER Result
;
176 #ifdef IOCTL_DISK_GET_LENGTH_INFO_IMPLEMENTED
178 DWORD BytesReturned
= 0;
180 sprintfW(szResult
, L
"\\\\.\\%c:", towupper(szDrive
[0]));
181 hVolume
= CreateFileW(szResult
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
182 if (hVolume
!= INVALID_HANDLE_VALUE
)
184 ret
= DeviceIoControl(hVolume
, IOCTL_DISK_GET_LENGTH_INFO
, NULL
, 0, (LPVOID
)&TotalNumberOfBytes
, sizeof(ULARGE_INTEGER
), &BytesReturned
, NULL
);
185 if (ret
&& StrFormatByteSizeW(LengthInformation
.Length
.QuadPart
, szResult
, sizeof(szResult
) / sizeof(WCHAR
)))
186 SendDlgItemMessageW(hwndDlg
, 14008, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szResult
);
188 CloseHandle(hVolume
);
190 TRACE("szResult %s hVOlume %p ret %d LengthInformation %ul Bytesreturned %d\n", debugstr_w(szResult
), hVolume
, ret
, LengthInformation
.Length
.QuadPart
, BytesReturned
);
192 if (ret
&& StrFormatByteSizeW(TotalNumberOfBytes
.QuadPart
, szResult
, sizeof(szResult
) / sizeof(WCHAR
)))
193 SendDlgItemMessageW(hwndDlg
, 14008, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szResult
);
196 if (StrFormatByteSizeW(TotalNumberOfBytes
.QuadPart
- FreeBytesAvailable
.QuadPart
, szResult
, sizeof(szResult
) / sizeof(WCHAR
)))
197 SendDlgItemMessageW(hwndDlg
, 14004, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szResult
);
199 if (StrFormatByteSizeW(FreeBytesAvailable
.QuadPart
, szResult
, sizeof(szResult
) / sizeof(WCHAR
)))
200 SendDlgItemMessageW(hwndDlg
, 14006, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szResult
);
202 Result
= GetFreeBytesShare(TotalNumberOfFreeBytes
, TotalNumberOfBytes
);
203 /* set free bytes percentage */
204 sprintfW(szResult
, L
"%02d%%", Result
.QuadPart
);
205 SendDlgItemMessageW(hwndDlg
, 14007, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)szResult
);
206 /* store used share amount */
207 Result
= LargeIntegerSubtract(ConvertUlongToLargeInteger(100), Result
);
208 sprintfW(szResult
, L
"%02d%%", Result
.QuadPart
);
209 SendDlgItemMessageW(hwndDlg
, 14005, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)szResult
);
210 if (LoadStringW(shell32_hInstance
, IDS_DRIVE_FIXED
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
)))
211 SendDlgItemMessageW(hwndDlg
, 14002, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)szBuffer
);
215 /* set drive description */
216 SendDlgItemMessageW(hwndDlg
, 14010, WM_GETTEXT
, (WPARAM
)50, (LPARAM
)szFormat
);
217 sprintfW(szBuffer
, szFormat
, szDrive
);
218 SendDlgItemMessageW(hwndDlg
, 14010, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)szBuffer
);
231 LPPROPSHEETPAGEW ppsp
;
232 LPDRAWITEMSTRUCT drawItem
;
234 PROCESS_INFORMATION pi
;
236 WCHAR szPath
[MAX_PATH
];
243 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
246 lpstr
= (WCHAR
*)ppsp
->lParam
;
247 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)lpstr
);
248 InitializeGeneralDriveDialog(hwndDlg
, lpstr
);
251 drawItem
= (LPDRAWITEMSTRUCT
)lParam
;
252 if (drawItem
->CtlID
>= 14013 && drawItem
->CtlID
<= 14015)
254 PaintStaticControls(hwndDlg
, drawItem
);
259 if (LOWORD(wParam
) == 14011)
261 lpstr
= (WCHAR
*)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
262 ZeroMemory( &si
, sizeof(si
) );
264 ZeroMemory( &pi
, sizeof(pi
) );
265 if (!GetSystemDirectoryW(szPath
, MAX_PATH
))
267 wcscat(szPath
, L
"\\cleanmgr.exe /D ");
268 length
= wcslen(szPath
);
269 szPath
[length
] = lpstr
[0];
270 szPath
[length
+1] = L
'\0';
271 if (CreateProcessW(NULL
, szPath
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
))
273 CloseHandle(pi
.hProcess
);
274 CloseHandle(pi
.hThread
);
279 lppsn
= (LPPSHNOTIFY
) lParam
;
280 if (LOWORD(wParam
) == 14001)
282 if (HIWORD(wParam
) == EN_CHANGE
)
284 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
288 if (lppsn
->hdr
.code
== PSN_APPLY
)
290 lpstr
= (LPWSTR
)GetWindowLong(hwndDlg
, DWLP_USER
);
291 if (lpstr
&& SendDlgItemMessageW(hwndDlg
, 14001, WM_GETTEXT
, sizeof(szPath
)/sizeof(WCHAR
), (LPARAM
)szPath
))
293 szPath
[(sizeof(szPath
)/sizeof(WCHAR
))-1] = L
'\0';
294 SetVolumeLabelW(lpstr
, szPath
);
296 SetWindowLong( hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
319 PROCESS_INFORMATION pi
;
320 WCHAR szPath
[MAX_PATH
];
321 WCHAR szArg
[MAX_PATH
];
324 LPPROPSHEETPAGEW ppsp
;
329 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
330 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)ppsp
->lParam
);
333 ZeroMemory( &si
, sizeof(si
) );
335 ZeroMemory( &pi
, sizeof(pi
) );
336 if (!GetSystemDirectoryW(szPath
, MAX_PATH
))
338 szDrive
= (WCHAR
*)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
339 switch(LOWORD(wParam
))
344 /// show checkdsk dialog
349 wcscpy(&szArg
[1], szPath
);
350 wcscat(szPath
, L
"\\mmc.exe");
351 wcscat(szArg
, L
"\\dfrg.msc\" ");
352 length
= wcslen(szArg
);
353 szArg
[length
] = szDrive
[0];
354 szArg
[length
+1] = L
':';
355 szArg
[length
+2] = L
'\0';
356 if (CreateProcessW(szPath
, szArg
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
))
358 CloseHandle(pi
.hProcess
);
359 CloseHandle(pi
.hThread
);
363 wcscat(szPath
, L
"\\ntbackup.exe");
364 if (CreateProcessW(szPath
, NULL
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
))
366 CloseHandle(pi
.hProcess
);
367 CloseHandle(pi
.hThread
);
385 Guids
[0] = GUID_DEVCLASS_DISKDRIVE
;
387 UNREFERENCED_PARAMETER(lParam
);
388 UNREFERENCED_PARAMETER(wParam
);
393 /* create the hardware page */
394 DeviceCreateHardwarePageEx(hwndDlg
,
396 sizeof(Guids
) / sizeof(Guids
[0]),
412 { "DRIVE_GENERAL_DLG", DriveGeneralDlg
},
413 { "DRIVE_EXTRA_DLG", DriveExtraDlg
},
414 { "DRIVE_HARDWARE_DLG", DriveHardwareDlg
},
419 AddPropSheetPageProc(HPROPSHEETPAGE hpage
, LPARAM lParam
)
421 PROPSHEETHEADER
*ppsh
= (PROPSHEETHEADER
*)lParam
;
422 if (ppsh
!= NULL
&& ppsh
->nPages
< MAX_PROPERTY_SHEET_PAGE
)
424 ppsh
->phpage
[ppsh
->nPages
++] = hpage
;
431 SH_ShowDriveProperties(WCHAR
* drive
)
434 HPROPSHEETPAGE hpsp
[MAX_PROPERTY_SHEET_PAGE
];
435 PROPSHEETHEADERW psh
;
438 WCHAR szName
[MAX_PATH
];
439 DWORD dwMaxComponent
, dwFileSysFlags
;
441 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
442 psh
.dwSize
= sizeof(PROPSHEETHEADERW
);
443 //psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
444 psh
.hwndParent
= NULL
;
449 if (GetVolumeInformationW(drive
, szName
, sizeof(szName
)/sizeof(WCHAR
), NULL
, &dwMaxComponent
,
450 &dwFileSysFlags
, NULL
, 0))
452 psh
.pszCaption
= szName
;
453 psh
.dwFlags
|= PSH_PROPTITLE
;
457 * check if disk is a really a local hdd
459 i
= LoadStringW(shell32_hInstance
, IDS_DRIVE_FIXED
, szName
, sizeof(szName
)/sizeof(WCHAR
));
460 if (i
> 0 && i
< (sizeof(szName
)/sizeof(WCHAR
)) + 6)
464 wcscpy(&szName
[i
+2], drive
);
472 for (i
= 0; i
< DRIVE_PROPERTY_PAGES
; i
++)
474 HPROPSHEETPAGE hprop
= SH_CreatePropertySheetPage(PropPages
[i
].resname
, PropPages
[i
].dlgproc
, (LPARAM
)drive
, NULL
);
477 hpsp
[psh
.nPages
] = hprop
;
482 hpsx
= SHCreatePropSheetExtArray(HKEY_CLASSES_ROOT
,
484 MAX_PROPERTY_SHEET_PAGE
-DRIVE_PROPERTY_PAGES
);
486 SHAddFromPropSheetExtArray(hpsx
,
487 (LPFNADDPROPSHEETPAGE
)AddPropSheetPageProc
,
490 ret
= PropertySheetW(&psh
);