Develop and Download Open Source Software

Browse CVS Repository

Contents of /tombo/Tombo/Src/MemoNote.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.35 - (show annotations) (download) (as text)
Wed Aug 23 15:31:53 2006 UTC (17 years, 7 months ago) by hirami
Branch: MAIN
CVS Tags: Tombo_2_0b2, Tombo_2_0b3, Tombo_2_0b1, Tombo_2_0b4, B228, B229, B226, B227, B224, B225, B222, B223, B231, B230, HEAD
Changes since 1.34: +2 -3 lines
File MIME type: text/x-c++src
- Multi repository support(yet completed)
- Fixes to YAE
	* Hang up when *.tdt points invalid position.

1 #include <windows.h>
2 #include <commctrl.h>
3 #include <tchar.h>
4 #include "Tombo.h"
5 #include "MemoNote.h"
6 #include "File.h"
7 #include "CryptManager.h"
8 #include "UniConv.h"
9 #include "PasswordManager.h"
10 #include "MemoManager.h"
11 #include "Property.h"
12 #include "TString.h"
13 #include "MemoInfo.h"
14 #include "Message.h"
15 #include "TomboURI.h"
16 #include "AutoPtr.h"
17
18 #include "Repository.h"
19
20 #define DEFAULT_HEADLINE MSG_DEFAULT_HEADLINE
21
22 /////////////////////////////////////////////
23 //
24 /////////////////////////////////////////////
25
26 MemoNote::MemoNote() : pPath(NULL)
27 {
28 }
29
30 MemoNote::~MemoNote()
31 {
32 delete [] pPath;
33 }
34
35 BOOL MemoNote::Init(LPCTSTR p)
36 {
37 if (pPath) delete [] pPath;
38 pPath = StringDup(p);
39 if (pPath == NULL) return FALSE;
40 return TRUE;
41 }
42
43 /////////////////////////////////////////////
44 // get note's URI
45 /////////////////////////////////////////////
46 BOOL MemoNote::GetURI(LPCTSTR pRepoName, TomboURI *pURI) const
47 {
48 return pURI->InitByNotePath(pRepoName, pPath);
49 }
50
51 /////////////////////////////////////////////
52 // Get memo data from file and decrypt if nesessary
53 /////////////////////////////////////////////
54
55 LPTSTR MemoNote::GetMemoBody(LPCTSTR pTopDir, PasswordManager *pMgr) const
56 {
57 DWORD nSize;
58 LPBYTE pData = GetMemoBodyNative(pTopDir, pMgr, &nSize);
59 if (!pData) return NULL;
60 SecureBufferAutoPointerByte ap(pData, nSize);
61 return ConvFileEncodingToTChar(pData);
62 }
63
64 LPBYTE PlainMemoNote::GetMemoBodyNative(LPCTSTR pTopDir, PasswordManager *pMgr, LPDWORD pSize) const
65 {
66 TString sFileName;
67 if (!sFileName.Join(pTopDir, TEXT("\\"), pPath)) return NULL;
68
69 File inf;
70 if (!inf.Open(sFileName.Get(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING)) return NULL;
71
72 LPBYTE pData = new BYTE[inf.FileSize() + 2];
73 if (pData == NULL) return NULL;
74
75 DWORD nSize = inf.FileSize();
76 if (!inf.Read(pData, &nSize)) return NULL;
77 pData[nSize] = TEXT('\0');
78 pData[nSize + 1] = TEXT('\0'); // sentinel for the UTF16 encoding file
79
80 *pSize = nSize;
81 return pData;
82 }
83
84 LPBYTE CryptedMemoNote::GetMemoBodySub(LPCTSTR pTopDir, PasswordManager *pMgr, LPDWORD pSize) const
85 {
86 BOOL bRegistedPassword = TRUE;
87
88 TString sFileName;
89 if (!sFileName.Join(pTopDir, TEXT("\\"), pPath)) return NULL;
90
91 LPBYTE pPlain;
92 for (DWORD i = 0; i < NUM_RETRY_INVALID_PASSWORD; i++) {
93 BOOL bCancel;
94 const char *pPassword = pMgr->Password(&bCancel, FALSE);
95 if (pPassword == NULL) {
96 if (bCancel) SetLastError(ERROR_CANCELLED);
97 pMgr->ForgetPassword();
98 return NULL;
99 }
100 CryptManager cMgr;
101 if (!cMgr.Init(pPassword)) return NULL;
102
103 pPlain = cMgr.LoadAndDecrypt(pSize, sFileName.Get());
104 if (pPlain != NULL) {
105 bRegistedPassword = TRUE;
106 break;
107 } else {
108 bRegistedPassword = FALSE;
109 pMgr->ForgetPassword();
110 }
111 }
112 return pPlain;
113 }
114
115 LPBYTE CryptedMemoNote::GetMemoBodyNative(LPCTSTR pTopDir, PasswordManager *pMgr, LPDWORD pSize) const
116 {
117 return GetMemoBodySub(pTopDir, pMgr, pSize);
118 }
119
120 /////////////////////////////////////////////
121 // Save note data
122 /////////////////////////////////////////////
123
124 BOOL MemoNote::SaveDataT(PasswordManager *pMgr, LPCTSTR pMemo, LPCTSTR pWriteFile)
125 {
126 LPBYTE pData;
127 DWORD nLen;
128
129 pData = ConvTCharToFileEncoding(pMemo, &nLen);
130 if (pData == NULL) return FALSE;
131 SecureBufferAutoPointerByte ap(pData, nLen);
132 return SaveData(pMgr, pData, nLen, pWriteFile);
133 }
134
135 BOOL PlainMemoNote::SaveData(PasswordManager *pMgr, const LPBYTE pData, DWORD nLen, LPCTSTR pWriteFile)
136 {
137 File outf;
138 if (!outf.Open(pWriteFile, GENERIC_WRITE, 0, OPEN_ALWAYS)) return FALSE;
139 if (!outf.Write((LPBYTE)pData, nLen)) return FALSE;
140 if (!outf.SetEOF()) return FALSE;
141 outf.Close();
142 return TRUE;
143 }
144
145 BOOL CryptedMemoNote::SaveData(PasswordManager *pMgr, const LPBYTE pData, DWORD nLen, LPCTSTR pWriteFile)
146 {
147 CryptManager cMgr;
148 BOOL bCancel;
149 const char *pPassword = pMgr->Password(&bCancel, TRUE);
150 if (pPassword == NULL) return FALSE;
151
152 if (!cMgr.Init(pPassword)) {
153 MessageBox(NULL, TEXT("In CryptedMemoNote::SaveData,CryptManager::Init failed"), TEXT("DEBUG"), MB_OK);
154 return FALSE;
155 }
156 return cMgr.EncryptAndStore(pData, nLen, pWriteFile);
157 }
158
159 /////////////////////////////////////////////
160 // ������
161 /////////////////////////////////////////////
162
163 MemoNote *MemoNote::Decrypt(LPCTSTR pTopDir, PasswordManager *pMgr, TString *pHeadLine, BOOL *pIsModified) const
164 {
165 return NULL;
166 }
167
168 MemoNote *CryptedMemoNote::Decrypt(LPCTSTR pTopDir, PasswordManager *pMgr, TString *pHeadLine, BOOL *pIsModified) const
169 {
170 // �����{������
171 LPTSTR pText = GetMemoBody(pTopDir, pMgr);
172 if (pText == NULL) return FALSE;
173 SecureBufferAutoPointerT ap(pText);
174
175 // �w�b�h���C������
176 TString sMemoDir;
177 if (!sMemoDir.GetDirectoryPath(pPath)) return FALSE;
178
179 TString sFullPath;
180 LPCTSTR pNotePath;
181 TString sHeadLine;
182 if (g_Property.GetKeepTitle()) {
183 if (!GetHeadLineFromFilePath(pPath, &sHeadLine)) return FALSE;
184 } else {
185 if (!GetHeadLineFromMemoText(pText, &sHeadLine)) return FALSE;
186 }
187
188 if (!GetHeadLinePath(pTopDir, sMemoDir.Get(), sHeadLine.Get(), TEXT(".txt"),
189 &sFullPath, &pNotePath, pHeadLine)) {
190 return FALSE;
191 }
192
193 // �V����MemoNote�C���X�^���X������
194 PlainMemoNote *p = new PlainMemoNote();
195 if (!p->Init(pNotePath)) {
196 WipeOutAndDeleteFile(sFullPath.Get());
197 return NULL;
198 }
199
200 // ��������
201 if (!p->SaveDataT(pMgr, pText, sFullPath.Get())) {
202 delete p;
203 return NULL;
204 }
205 return p;
206 }
207
208 /////////////////////////////////////////////
209 // �f�[�^������
210 /////////////////////////////////////////////
211
212 BOOL MemoNote::DeleteMemoData(LPCTSTR pTopDir) const
213 {
214 TString sFileName;
215 if (!sFileName.Join(pTopDir, TEXT("\\"), pPath)) return FALSE;
216
217 // �t������������������������������������������
218 if (MemoPath()) {
219 MemoInfo mi(pTopDir);
220 mi.DeleteInfo(MemoPath());
221 }
222
223 return WipeOutAndDeleteFile(sFileName.Get());
224 }
225
226 /////////////////////////////////////////////
227 // �C���X�^���X������
228 /////////////////////////////////////////////
229
230 MemoNote *PlainMemoNote::GetNewInstance() const
231 {
232 return new PlainMemoNote();
233 }
234
235 MemoNote *CryptedMemoNote::GetNewInstance() const
236 {
237 return new CryptedMemoNote();
238 }
239
240 /////////////////////////////////////////////
241 // �g���q������
242 /////////////////////////////////////////////
243
244 LPCTSTR PlainMemoNote::GetExtension()
245 {
246 return TEXT(".txt");
247 }
248
249 LPCTSTR CryptedMemoNote::GetExtension()
250 {
251 return TEXT(".chi");
252 }
253
254 /////////////////////////////////////////////
255 // �w�b�h���C��������
256 /////////////////////////////////////////////
257 // �����{�������w�b�h���C�������������������������B
258 //
259 // �w�b�h���C����
260 // �E������1�s��������
261 // �E1�s�������������������������A������������
262 // �������B
263
264 BOOL MemoNote::GetHeadLineFromMemoText(LPCTSTR pMemo, TString *pHeadLine)
265 {
266 // �w�b�h���C�������J�E���g
267 LPCTSTR p = pMemo;
268 DWORD n = 0;
269 while(*p) {
270 if ((*p == TEXT('\r')) || (*p == TEXT('\n'))) break;
271 #ifndef _WIN32_WCE
272 if (IsDBCSLeadByte(*p)) {
273 p += 2;
274 n += 2;
275 continue;
276 }
277 #endif
278 n++;
279 p++;
280 }
281
282 TString sHeadLineCand;
283 if (!sHeadLineCand.Alloc(n + 1)) return FALSE;
284 _tcsncpy(sHeadLineCand.Get(), pMemo, n);
285 *(sHeadLineCand.Get() + n) = TEXT('\0');
286
287 // �����m���E�R�s�[
288 if (!pHeadLine->Alloc(n + 1)) return FALSE;
289 DropInvalidFileChar(pHeadLine->Get(), sHeadLineCand.Get());
290 TrimRight(pHeadLine->Get());
291
292 if (_tcslen(pHeadLine->Get()) == 0) {
293 if (!pHeadLine->Set(DEFAULT_HEADLINE)) return FALSE;
294 }
295
296 return TRUE;
297 }
298
299 /////////////////////////////////////////////
300 // �t�@�C���������`�F�b�N
301 /////////////////////////////////////////////
302
303 static BOOL IsFileExist(LPCTSTR pFileName)
304 {
305 HANDLE hFile = CreateFile(pFileName, GENERIC_READ, FILE_SHARE_WRITE, NULL,
306 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
307 if (hFile == INVALID_HANDLE_VALUE) {
308 return FALSE;
309 } else {
310 CloseHandle(hFile);
311 return TRUE;
312 }
313 }
314
315 // �^�������������������t�@�C��������������
316
317 // IN: pMemoPath : �������p�X(TOPDIR�����������p�X,�t�@�C������������)
318 // pHeadLine : �w�b�h���C��������
319 // pExt : �t�^�����g���q
320 // OUT: pFullPath : �������t���p�X
321 // ppNotePath : �������p�X(TOPDIR�����������p�X,�t�@�C�����������A
322 // �K�v����"(n)"���f�B���N�g����������������������������������
323 // pNewHeadLine: �����\���p�V�w�b�h���C��(�K�v��������"(n)"���t�^����������)
324
325 BOOL MemoNote::GetHeadLinePath(LPCTSTR pTopDir, LPCTSTR pMemoPath, LPCTSTR pHeadLine, LPCTSTR pExt,
326 TString *pFullPath, LPCTSTR *ppNotePath, TString *pNewHeadLine)
327 {
328 DWORD n = _tcslen(pHeadLine);
329 if (n < _tcslen(DEFAULT_HEADLINE)) n = _tcslen(DEFAULT_HEADLINE);
330
331 DWORD nHeadLineLen = n + 20;
332 DWORD nFullPathLen = _tcslen(pTopDir) + 1 +
333 _tcslen(pMemoPath) + nHeadLineLen + _tcslen(pExt);
334 if (!pNewHeadLine->Alloc(nHeadLineLen + 1)) return FALSE;
335 if (!pFullPath->Alloc(nFullPathLen + 1)) return FALSE;
336
337 DropInvalidFileChar(pNewHeadLine->Get(), pHeadLine);
338 if (_tcslen(pNewHeadLine->Get()) == 0) _tcscpy(pNewHeadLine->Get(), DEFAULT_HEADLINE);
339 wsprintf(pFullPath->Get(), TEXT("%s\\%s%s"), pTopDir, pMemoPath, pNewHeadLine->Get());
340
341 LPTSTR p = pFullPath->Get();
342 LPTSTR q = p + _tcslen(p);
343 LPTSTR r = pNewHeadLine->Get() + _tcslen(pNewHeadLine->Get());
344
345 *ppNotePath = pFullPath->Get() + _tcslen(pTopDir) + 1;
346
347 // �t�@�C�������m��
348 // �������t�@�C��������������������"(n)"���t������
349 _tcscpy(q, pExt);
350 if (!IsFileExist(p)) return TRUE;
351
352 DWORD i = 1;
353 do {
354 wsprintf(q, TEXT("(%d)%s"), i, pExt);
355 wsprintf(r, TEXT("(%d)"), i);
356 i++;
357 } while(IsFileExist(p));
358 return TRUE;
359 }
360
361 ////////////////////////////////////////////////////////
362 // �t�@�C���p�X�����w�b�h���C��������
363 ////////////////////////////////////////////////////////
364 // �{�����Q�������������A�������w�b�h���C�����������K���������v�����������������B
365
366 BOOL MemoNote::GetHeadLineFromFilePath(LPCTSTR pFilePath, TString *pHeadLine)
367 {
368 LPCTSTR p = pFilePath;
369 LPCTSTR q = NULL;
370 #ifdef _WIN32_WCE
371 while (*p) {
372 if (*p == TEXT('\\')) q = p;
373 p++;
374 }
375 #else
376 while (*p) {
377 if (*p == TEXT('\\')) q = p;
378 if (IsDBCSLeadByte(*p)) {
379 p++;
380 }
381 p++;
382 }
383 #endif
384 if (q == NULL) {
385 if (!pHeadLine->Set(pFilePath)) return FALSE;
386 } else {
387 if (!pHeadLine->Set(q + 1)) return FALSE;
388 }
389
390 pHeadLine->ChopExtension();
391 pHeadLine->ChopFileNumber();
392 return TRUE;
393 }
394
395 ////////////////////////////////////////////////////////
396 // �����t�@�C�����R�s�[�����C���X�^���X������
397 ////////////////////////////////////////////////////////
398
399 MemoNote *MemoNote::CopyMemo(LPCTSTR pTopDir, const MemoNote *pOrig, LPCTSTR pMemoPath, TString *pHeadLine)
400 {
401 MemoNote *pNote;
402 pNote = pOrig->GetNewInstance();
403 if (pNote == NULL) {
404 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
405 return NULL;
406 }
407
408 TString sNewFullPath;
409 LPCTSTR pNotePath;
410 TString sHeadLine;
411
412 if (!GetHeadLineFromFilePath(pOrig->MemoPath(), &sHeadLine)) {
413 delete pNote;
414 return NULL;
415 }
416 if (!GetHeadLinePath(pTopDir, pMemoPath, sHeadLine.Get(), pNote->GetExtension(), &sNewFullPath, &pNotePath, pHeadLine)) {
417 delete pNote;
418 return NULL;
419 }
420
421 TString sOrigPath;
422 if (!sOrigPath.Join(pTopDir, TEXT("\\"), pOrig->MemoPath())) {
423 delete pNote;
424 return NULL;
425 }
426
427 if (!CopyFile(sOrigPath.Get(), sNewFullPath.Get(), TRUE) || !pNote->Init(pNotePath)) {
428 delete pNote;
429 return NULL;
430 }
431 // the result of copying tdt is not checked.
432 TString sOrigTDT, sNewTDT;
433 if (sOrigTDT.Join(sOrigPath.Get(), TEXT(".tdt")) &&
434 sNewTDT.Join(sNewFullPath.Get(), TEXT(".tdt"))) {
435 CopyFile(sOrigTDT.Get(), sNewTDT.Get(), TRUE);
436 }
437 return pNote;
438 }
439
440 /////////////////////////////////////////////
441 // �t�@�C�������X
442 /////////////////////////////////////////////
443
444 BOOL MemoNote::Rename(LPCTSTR pTopDir, LPCTSTR pNewName)
445 {
446 TString sPath;
447 if (!sPath.GetDirectoryPath(pPath)) return FALSE;
448
449 if (_tcslen(pNewName) == 0) {
450 SetLastError(ERROR_NO_DATA);
451 return FALSE;
452 }
453
454 // �V����pPath�������m��
455 DWORD nBaseLen = _tcslen(sPath.Get());
456 LPTSTR pNewPath = new TCHAR[nBaseLen + _tcslen(pNewName) + _tcslen(GetExtension()) + 6 + 1];
457 if (pNewPath == NULL) return FALSE;
458
459 // �VpPath����
460 _tcscpy(pNewPath, sPath.Get());
461 DropInvalidFileChar(pNewPath + nBaseLen, pNewName);
462 _tcscat(pNewPath + nBaseLen, GetExtension());
463
464 // �t�@�C�������l�[���p�p�X����
465 TString sOldFullPath;
466 TString sNewFullPath;
467 if (!sOldFullPath.Join(pTopDir, TEXT("\\"), pPath) ||
468 !sNewFullPath.Join(pTopDir, TEXT("\\"), pNewPath)) {
469 delete [] pNewPath;
470 return FALSE;
471 }
472
473 // �t�@�C�������l�[�����s
474 if (!MoveFile(sOldFullPath.Get(), sNewFullPath.Get())) {
475 delete [] pNewPath;
476 return FALSE;
477 }
478
479 // *.tdt�����l�[�������s
480 MemoInfo mi(pTopDir);
481 mi.RenameInfo(sOldFullPath.Get(), sNewFullPath.Get());
482
483 delete [] pPath;
484 pPath = pNewPath;
485
486 return TRUE;
487 }
488
489 /////////////////////////////////////////////
490 // Check is this file memo?
491 /////////////////////////////////////////////
492
493 DWORD MemoNote::IsNote(LPCTSTR pFile)
494 {
495 DWORD len = _tcslen(pFile);
496 if (len <= 4) return NOTE_TYPE_NO;
497
498 LPCTSTR p = pFile + len - 4;
499
500 DWORD nType;
501 if (_tcsicmp(p, TEXT(".txt")) == 0) {
502 nType = NOTE_TYPE_PLAIN;
503 } else if (_tcsicmp(p, TEXT(".chi")) == 0) {
504 nType = NOTE_TYPE_CRYPTED;
505 } else if (_tcsicmp(p, TEXT(".chs")) == 0) {
506 nType = NOTE_TYPE_CRYPTED;
507 } else if (_tcsicmp(p, TEXT(".tdt")) == 0) {
508 nType = NOTE_TYPE_TDT;
509 } else {
510 nType = NOTE_TYPE_NO;
511 }
512 return nType;
513 }
514
515 /////////////////////////////////////////////
516 // set the note path
517 /////////////////////////////////////////////
518
519 BOOL MemoNote::SetMemoPath(LPCTSTR p)
520 {
521 LPTSTR pNewPath = StringDup(p);
522 if (pNewPath == NULL) return FALSE;
523 delete [] pPath;
524 pPath = pNewPath;
525 return TRUE;
526 }
527
528 /////////////////////////////////////////////
529 // MemoNote object factory
530 /////////////////////////////////////////////
531
532 BOOL MemoNote::MemoNoteFactory(LPCTSTR pFile, MemoNote **ppNote)
533 {
534 *ppNote = NULL;
535
536 DWORD nType = IsNote(pFile);
537 if (nType == NOTE_TYPE_NO || nType == NOTE_TYPE_TDT) return TRUE;
538 if (nType == NOTE_TYPE_PLAIN) {
539 *ppNote = new PlainMemoNote();
540 } else {
541 *ppNote = new CryptedMemoNote();
542 }
543
544 if (*ppNote == NULL) {
545 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
546 return FALSE;
547 }
548
549 if (!(*ppNote)->Init(pFile)) {
550 delete (*ppNote);
551 *ppNote = NULL;
552 return FALSE;
553 }
554 return TRUE;
555 }
556
557 MemoNote *MemoNote::MemoNoteFactory(const TomboURI *pURI)
558 {
559 LPCTSTR pURIPath = pURI->GetPath() + 1;
560 LPTSTR pBuf = StringDup(pURIPath);
561 if (pBuf == NULL) return NULL;
562
563 // replace '/' to '\'
564 LPTSTR p = pBuf;
565 while(p) {
566 p = _tcschr(p, TEXT('/'));
567 if (p) {
568 *p = TEXT('\\');
569 }
570 }
571 MemoNote *pNote = NULL;
572 MemoNote::MemoNoteFactory(pBuf, &pNote);
573 delete [] pBuf;
574 return pNote;
575 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26