Windows: Prevent overflow during percent used calc in Explorer Shell Ext
[openafs.git] / src / WINNT / client_exp / volumeinfo.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include "stdafx.h"
11 #include <winsock2.h>
12 #include <ws2tcpip.h>
13
14 extern "C" {
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 }
18
19 #include "afs_shl_ext.h"
20 #include "volume_info.h"
21 #include "partition_info_dlg.h"
22 #include "volume_inf.h"
23 #include "gui2fs.h"
24 #include <limits.h>
25 #include "msgs.h"
26
27 #ifdef _DEBUG
28 #define new DEBUG_NEW
29 #undef THIS_FILE
30 static char THIS_FILE[] = __FILE__;
31 #endif
32
33 /////////////////////////////////////////////////////////////////////////////
34 // CVolumeInfo dialog
35
36
37 CVolumeInfo::CVolumeInfo(CWnd* pParent /*=NULL*/)
38         : CDialog()
39 {
40         InitModalIndirect (TaLocale_GetDialogResource (CVolumeInfo::IDD), pParent);
41
42         //{{AFX_DATA_INIT(CVolumeInfo)
43         m_nNewQuota = 0;
44         //}}AFX_DATA_INIT
45         
46         m_pVolInfo = 0;
47         m_nCurIndex = -1;
48 }
49
50 CVolumeInfo::~CVolumeInfo()
51 {
52         if (m_pVolInfo != 0)
53                 delete [] m_pVolInfo;
54 }
55
56 void CVolumeInfo::DoDataExchange(CDataExchange* pDX)
57 {
58         CDialog::DoDataExchange(pDX);
59         //{{AFX_DATA_MAP(CVolumeInfo)
60         DDX_Control(pDX, IDC_QUOTA_SPIN, m_QuotaSpin);
61         DDX_Control(pDX, IDOK, m_Ok);
62         DDX_Control(pDX, IDC_PARTITION_INFO, m_ShowPartInfo);
63         DDX_Control(pDX, IDC_LIST, m_List);
64         DDX_Text(pDX, IDC_NEW_QUOTA, m_nNewQuota);
65         //}}AFX_DATA_MAP
66 }
67
68 BEGIN_MESSAGE_MAP(CVolumeInfo, CDialog)
69         //{{AFX_MSG_MAP(CVolumeInfo)
70         ON_LBN_SELCHANGE(IDC_LIST, OnSelChangeList)
71         ON_BN_CLICKED(IDC_PARTITION_INFO, OnPartitionInfo)
72         ON_EN_CHANGE(IDC_NEW_QUOTA, OnChangeNewQuota)
73         ON_NOTIFY(UDN_DELTAPOS, IDC_QUOTA_SPIN, OnDeltaPosQuotaSpin)
74         ON_BN_CLICKED(IDHELP, OnHelp)
75         //}}AFX_MSG_MAP
76 END_MESSAGE_MAP()
77
78 /////////////////////////////////////////////////////////////////////////////
79 // CVolumeInfo message handlers
80
81 BOOL CVolumeInfo::OnInitDialog() 
82 {
83         ASSERT(m_Files.GetSize() > 0);
84
85         CDialog::OnInitDialog();
86
87         int tabs[] = { 79, 164, 214, 260, 301 };
88         
89         m_List.SetTabStops(sizeof(tabs) / sizeof(int), tabs);
90
91         m_pVolInfo = new CVolInfo[m_Files.GetSize()];
92
93         for (int i = 0; i < m_Files.GetSize(); i++) {
94                 GetVolumeInfo(m_Files[i], m_pVolInfo[i]);
95                 // Check if this is a duplicate entry (same volume as earlier entry)
96                 for (int j = 0; j < i; j++) {
97                         if (m_pVolInfo[j].m_nID == m_pVolInfo[i].m_nID)
98                                 m_pVolInfo[i].m_nDup = j;
99                                 break;
100                 }
101         }
102
103         ShowInfo();
104
105         m_QuotaSpin.SetRange(UD_MINVAL, UD_MAXVAL);
106         m_QuotaSpin.SetPos(0);
107
108         return TRUE;  // return TRUE unless you set the focus to a control
109                       // EXCEPTION: OCX Property Pages should return FALSE
110 }
111
112 int CVolumeInfo::GetCurVolInfoIndex()
113 {
114         int nListIndex = m_List.GetCurSel();
115         ASSERT(nListIndex >= 0);
116
117         int nIndex = m_List.GetItemData(nListIndex);
118         ASSERT(nIndex >= 0);
119
120         if (m_pVolInfo[nIndex].m_nDup != -1)
121                 return m_pVolInfo[nIndex].m_nDup;
122
123         return nIndex;
124 }
125
126 void CVolumeInfo::OnSelChangeList() 
127 {
128         m_nCurIndex = GetCurVolInfoIndex();
129         if (m_nCurIndex < 0)
130                 return;
131
132         m_nNewQuota = m_pVolInfo[m_nCurIndex].m_nNewQuota;
133
134         m_ShowPartInfo.EnableWindow(TRUE);
135         CWnd *pNewQuota = GetDlgItem(IDC_NEW_QUOTA);
136         pNewQuota->EnableWindow(TRUE);
137
138         m_QuotaSpin.EnableWindow(TRUE);
139         m_QuotaSpin.SetPos(0);
140
141         UpdateData(FALSE);
142 }
143
144 void CVolumeInfo::OnPartitionInfo() 
145 {
146         CPartitionInfoDlg dlg;
147
148         ASSERT(m_nCurIndex >= 0);
149
150         dlg.SetValues(m_pVolInfo[m_nCurIndex].m_nPartSize, m_pVolInfo[m_nCurIndex].m_nPartFree);
151
152         dlg.DoModal();
153 }
154
155 void CVolumeInfo::SetFiles(const CStringArray& files)
156 {
157         m_Files.RemoveAll();
158
159         m_Files.Copy(files);
160 }
161
162 void CVolumeInfo::OnChangeNewQuota() 
163 {
164         if (m_List.m_hWnd == 0)
165                 return;
166
167         CString strQuota;
168         GetDlgItem(IDC_NEW_QUOTA)->GetWindowText(strQuota);
169
170         if (strQuota.IsEmpty())
171                 return;
172
173         if (!UpdateData(TRUE))
174                 return;
175
176         ASSERT(m_nCurIndex >= 0);
177
178         m_pVolInfo[m_nCurIndex].m_nNewQuota = m_nNewQuota;
179
180         if (m_pVolInfo[m_nCurIndex].m_nNewQuota != m_pVolInfo[m_nCurIndex].m_nQuota)
181                 m_Ok.EnableWindow(TRUE);
182
183         ShowInfo();
184 }
185
186 void CVolumeInfo::OnOK() 
187 {
188         for (int i = 0; i < m_Files.GetSize(); i++) {
189                 if ((m_pVolInfo[i].m_nDup == -1) && (m_pVolInfo[i].m_nQuota != m_pVolInfo[i].m_nNewQuota)) {
190 //                      CString strQuota;
191 //                      strQuota.Format("= %ld", m_pVolInfo[i].m_nNewQuota);
192 //                      AfxMessageBox("Setting quota for volume: " + m_pVolInfo[i].m_strName + strQuota);
193                         SetVolInfo(m_pVolInfo[i]);
194                 }
195         }
196         
197         CDialog::OnOK();
198 }
199
200 void CVolumeInfo::OnDeltaPosQuotaSpin(NMHDR* pNMHDR, LRESULT* pResult) 
201 {
202         NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
203         
204         unsigned __int64 nNewQuota = m_nNewQuota + pNMUpDown->iDelta * 1024;
205         if (nNewQuota < 0)
206                 return;
207
208         m_nNewQuota = nNewQuota;
209         
210         UpdateData(FALSE);
211
212         OnChangeNewQuota();
213
214         *pResult = 0;
215 }
216
217 void CVolumeInfo::ShowInfo()
218 {
219         m_List.ResetContent();
220         
221         for (int i = 0; i < m_Files.GetSize(); i++) {
222
223                 CString strEntry;
224                 if (m_pVolInfo[i].m_strErrorMsg.GetLength() > 0)
225                         strEntry = m_pVolInfo[i].m_strFileName + "\t(Error:  " + m_pVolInfo[i].m_strErrorMsg + ")";
226                 else {
227
228                         unsigned __int64 nQuota;
229                         if (m_pVolInfo[i].m_nDup == -1)
230                                 nQuota = m_pVolInfo[i].m_nNewQuota;
231                         else
232                                 nQuota = m_pVolInfo[m_pVolInfo[i].m_nDup].m_nNewQuota;
233
234                         if (nQuota != 0) {
235                             LONG nPercentUsed = (LONG)((double)m_pVolInfo[i].m_nUsed / nQuota * 100);
236                             strEntry.Format(_T("%s\t%s\t%ld\t%ldK\t%ldK\t%ld%%"),
237                                             m_pVolInfo[i].m_strFileName,
238                                             m_pVolInfo[i].m_strName,
239                                             m_pVolInfo[i].m_nID, nQuota,
240                                             m_pVolInfo[i].m_nUsed, nPercentUsed);
241                         } else {
242                             strEntry.Format(_T("%s\t%s\t%ld\tUnlimited\t%ldK"),
243                                             m_pVolInfo[i].m_strFileName,
244                                             m_pVolInfo[i].m_strName,
245                                         m_pVolInfo[i].m_nID, m_pVolInfo[i].m_nUsed);
246                         }
247                 }
248
249                 int nListIndex = m_List.AddString(strEntry);
250                 ASSERT(nListIndex >= 0);
251                 VERIFY(m_List.SetItemData(nListIndex, i) != LB_ERR);
252         }
253 }
254
255 void CVolumeInfo::OnHelp() 
256 {
257         ShowHelp(m_hWnd, VOLUME_INFO_HELP_ID);
258 }
259