Annotation of truecrypt/common/keyfiles.c, revision 1.1.1.13

1.1.1.5   root        1: /*
1.1.1.13! root        2:  Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
1.1       root        3: 
1.1.1.13! root        4:  Governed by the TrueCrypt License 2.8 the full text of which is contained in
        !             5:  the file License.txt included in TrueCrypt binary and source code distribution
        !             6:  packages.
1.1       root        7: */
                      8: 
1.1.1.5   root        9: #include <stdlib.h>
                     10: #include <string.h>
1.1       root       11: #include <sys/stat.h>
                     12: #include <sys/types.h>
                     13: 
                     14: #include "Tcdefs.h"
                     15: #include "Keyfiles.h"
                     16: #include "Crc.h"
                     17: 
                     18: #include <io.h>
                     19: #include "Dlgcode.h"
                     20: #include "Language.h"
1.1.1.9   root       21: #include "SecurityToken.h"
                     22: #include "Common/resource.h"
                     23: #include "Platform/ForEach.h"
                     24: 
                     25: using namespace TrueCrypt;
1.1       root       26: 
                     27: #define stat _stat
                     28: #define S_IFDIR _S_IFDIR
                     29: #define snprintf _snprintf
                     30: 
                     31: 
                     32: KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile)
                     33: {
                     34:        KeyFile *kf = firstKeyFile;
                     35: 
                     36:        if (firstKeyFile != NULL)
                     37:        {
                     38:                while (kf->Next)
                     39:                        kf = kf->Next;
                     40: 
                     41:                kf->Next = keyFile;
                     42:        }
                     43:        else
                     44:                firstKeyFile = keyFile;
                     45: 
                     46:        keyFile->Next = NULL;
                     47: 
                     48:        return firstKeyFile;
                     49: }
                     50: 
                     51: 
                     52: // Returns first keyfile, NULL if last keyfile was removed
                     53: static KeyFile *KeyFileRemove (KeyFile *firstKeyFile, KeyFile *keyFile)
                     54: {
                     55:        KeyFile *prevkf = NULL, *kf = firstKeyFile;
                     56: 
                     57:        if (firstKeyFile == NULL) return NULL;
                     58:        do
                     59:        {
                     60:                if (kf == keyFile)
                     61:                {
                     62:                        if (prevkf == NULL)
                     63:                                firstKeyFile = kf->Next;
                     64:                        else
                     65:                                prevkf->Next = kf->Next;
                     66: 
1.1.1.7   root       67:                        burn (keyFile, sizeof(*keyFile));       // wipe
1.1       root       68:                        free (keyFile);
                     69:                        break;
                     70:                }
                     71:                prevkf = kf;
                     72:        }
                     73:        while (kf = kf->Next);
                     74: 
                     75:        return firstKeyFile;
                     76: }
                     77: 
                     78: 
                     79: void KeyFileRemoveAll (KeyFile **firstKeyFile)
                     80: {
                     81:        KeyFile *kf = *firstKeyFile;
                     82:        while (kf != NULL)
                     83:        {
                     84:                KeyFile *d = kf;
                     85:                kf = kf->Next;
                     86:                burn (d, sizeof(*d));   // wipe
                     87:                free (d);
                     88:        }
                     89: 
                     90:        *firstKeyFile = NULL;
                     91: }
                     92: 
                     93: 
                     94: KeyFile *KeyFileClone (KeyFile *keyFile)
                     95: {
                     96:        KeyFile *clone;
                     97: 
                     98:        if (keyFile == NULL) return NULL;
                     99: 
1.1.1.9   root      100:        clone = (KeyFile *) malloc (sizeof (KeyFile));
1.1       root      101:        strcpy (clone->FileName, keyFile->FileName);
                    102:        clone->Next = NULL;
                    103:        return clone;
                    104: }
                    105: 
                    106: 
                    107: KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile)
                    108: {
                    109:        KeyFile *cloneFirstKeyFile = KeyFileClone (firstKeyFile);
                    110:        KeyFile *kf;
                    111: 
                    112:        if (firstKeyFile == NULL) return NULL;
                    113:        kf = firstKeyFile->Next;
                    114:        while (kf != NULL)
                    115:        {
                    116:                KeyFileAdd (cloneFirstKeyFile, KeyFileClone (kf));
                    117:                kf = kf->Next;
                    118:        }
                    119: 
                    120:        return cloneFirstKeyFile;
                    121: }
                    122: 
                    123: 
1.1.1.6   root      124: static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
1.1       root      125: {
                    126:        FILE *f;
                    127:        unsigned __int8 buffer[64 * 1024];
                    128:        unsigned __int32 crc = 0xffffffff;
                    129:        int writePos = 0;
                    130:        size_t bytesRead, totalRead = 0;
1.1.1.6   root      131:        int status = TRUE;
1.1       root      132: 
                    133:        HANDLE src;
                    134:        FILETIME ftCreationTime;
                    135:        FILETIME ftLastWriteTime;
                    136:        FILETIME ftLastAccessTime;
                    137: 
                    138:        BOOL bTimeStampValid = FALSE;
                    139: 
1.1.1.6   root      140:        /* Remember the last access time of the keyfile. It will be preserved in order to prevent
                    141:        an adversary from determining which file may have been used as keyfile. */
                    142:        src = CreateFile (keyFile->FileName,
                    143:                GENERIC_READ | GENERIC_WRITE,
                    144:                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1.1       root      145: 
1.1.1.6   root      146:        if (src != INVALID_HANDLE_VALUE)
                    147:        {
                    148:                if (GetFileTime ((HANDLE) src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
                    149:                        bTimeStampValid = TRUE;
                    150:        }
1.1       root      151: 
                    152:        f = fopen (keyFile->FileName, "rb");
                    153:        if (f == NULL) return FALSE;
                    154: 
                    155:        while ((bytesRead = fread (buffer, 1, sizeof (buffer), f)) > 0)
                    156:        {
                    157:                size_t i;
                    158: 
1.1.1.6   root      159:                if (ferror (f))
                    160:                {
                    161:                        status = FALSE;
                    162:                        goto close;
                    163:                }
                    164: 
1.1       root      165:                for (i = 0; i < bytesRead; i++)
                    166:                {
                    167:                        crc = UPDC32 (buffer[i], crc);
                    168: 
                    169:                        keyPool[writePos++] += (unsigned __int8) (crc >> 24);
                    170:                        keyPool[writePos++] += (unsigned __int8) (crc >> 16);
                    171:                        keyPool[writePos++] += (unsigned __int8) (crc >> 8);
                    172:                        keyPool[writePos++] += (unsigned __int8) crc;
                    173: 
                    174:                        if (writePos >= KEYFILE_POOL_SIZE)
                    175:                                writePos = 0;
                    176: 
                    177:                        if (++totalRead >= KEYFILE_MAX_READ_LEN)
                    178:                                goto close;
                    179:                }
                    180:        }
                    181: 
1.1.1.6   root      182:        if (ferror (f))
1.1.1.9   root      183:        {
                    184:                status = FALSE;
                    185:        }
                    186:        else if (totalRead == 0)
                    187:        {
1.1.1.6   root      188:                status = FALSE;
1.1.1.9   root      189:                SetLastError (ERROR_HANDLE_EOF); 
                    190:        }
1.1.1.6   root      191: 
1.1       root      192: close:
1.1.1.9   root      193:        DWORD err = GetLastError();
1.1       root      194:        fclose (f);
                    195: 
1.1.1.9   root      196:        if (bTimeStampValid && !IsFileOnReadOnlyFilesystem (keyFile->FileName))
1.1       root      197:        {
                    198:                // Restore the keyfile timestamp
1.1.1.13! root      199:                SetFileTime (src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
1.1       root      200:                CloseHandle (src);
                    201:        }
                    202: 
1.1.1.9   root      203:        SetLastError (err);
1.1.1.6   root      204:        return status;
1.1       root      205: }
                    206: 
                    207: 
1.1.1.6   root      208: BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile)
1.1       root      209: {
                    210:        BOOL status = TRUE;
                    211:        KeyFile kfSubStruct;
                    212:        KeyFile *kf;
                    213:        KeyFile *kfSub = &kfSubStruct;
                    214:        static unsigned __int8 keyPool [KEYFILE_POOL_SIZE];
1.1.1.10  root      215:        size_t i;
1.1       root      216:        struct stat statStruct;
                    217:        char searchPath [TC_MAX_PATH*2];
                    218:        struct _finddata_t fBuf;
                    219:        intptr_t searchHandle;
                    220: 
                    221:        if (firstKeyFile == NULL) return TRUE;
                    222: 
                    223:        VirtualLock (keyPool, sizeof (keyPool));
                    224:        memset (keyPool, 0, sizeof (keyPool));
                    225: 
                    226:        for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
                    227:        {
1.1.1.9   root      228:                // Determine whether it's a security token path
                    229:                try
                    230:                {
                    231:                        if (SecurityToken::IsKeyfilePathValid (SingleStringToWide (kf->FileName)))
                    232:                        {
                    233:                                // Apply security token keyfile
                    234:                                vector <byte> keyfileData;
                    235:                                SecurityToken::GetKeyfileData (SecurityTokenKeyfile (SingleStringToWide (kf->FileName)), keyfileData);
                    236: 
                    237:                                if (keyfileData.empty())
                    238:                                {
                    239:                                        SetLastError (ERROR_HANDLE_EOF); 
                    240:                                        handleWin32Error (MainDlg);
                    241:                                        Error ("ERR_PROCESS_KEYFILE");
                    242:                                        status = FALSE;
                    243:                                        continue;
                    244:                                }
                    245: 
                    246:                                unsigned __int32 crc = 0xffffffff;
                    247:                                int writePos = 0;
                    248:                                size_t totalRead = 0;
                    249: 
                    250:                                for (size_t i = 0; i < keyfileData.size(); i++)
                    251:                                {
                    252:                                        crc = UPDC32 (keyfileData[i], crc);
                    253: 
                    254:                                        keyPool[writePos++] += (unsigned __int8) (crc >> 24);
                    255:                                        keyPool[writePos++] += (unsigned __int8) (crc >> 16);
                    256:                                        keyPool[writePos++] += (unsigned __int8) (crc >> 8);
                    257:                                        keyPool[writePos++] += (unsigned __int8) crc;
                    258: 
                    259:                                        if (writePos >= KEYFILE_POOL_SIZE)
                    260:                                                writePos = 0;
                    261: 
                    262:                                        if (++totalRead >= KEYFILE_MAX_READ_LEN)
                    263:                                                break;
                    264:                                }
                    265: 
                    266:                                burn (&keyfileData.front(), keyfileData.size());
                    267:                                continue;
                    268:                        }
                    269:                }
                    270:                catch (Exception &e)
                    271:                {
                    272:                        e.Show (NULL);
                    273:                        return FALSE;
                    274:                }
                    275: 
1.1       root      276:                // Determine whether it's a path or a file
                    277:                if (stat (kf->FileName, &statStruct) != 0)
                    278:                {
1.1.1.6   root      279:                        handleWin32Error (MainDlg);
1.1       root      280:                        Error ("ERR_PROCESS_KEYFILE");
                    281:                        status = FALSE;
                    282:                        continue;
                    283:                }
                    284: 
                    285:                if (statStruct.st_mode & S_IFDIR)               // If it's a directory
                    286:                {
                    287:                        /* Find and process all keyfiles in the directory */
1.1.1.13! root      288:                        int keyfileCount = 0;
1.1       root      289: 
                    290:                        snprintf (searchPath, sizeof (searchPath), "%s\\*.*", kf->FileName);
                    291:                        if ((searchHandle = _findfirst (searchPath, &fBuf)) == -1)
                    292:                        {
1.1.1.6   root      293:                                handleWin32Error (MainDlg);
1.1       root      294:                                Error ("ERR_PROCESS_KEYFILE_PATH");
                    295:                                status = FALSE;
                    296:                                continue;
                    297:                        }
                    298: 
                    299:                        do
                    300:                        {
                    301:                                snprintf (kfSub->FileName, sizeof(kfSub->FileName), "%s%c%s", kf->FileName,
                    302:                                        '\\',
                    303:                                        fBuf.name
                    304:                                        );
                    305: 
                    306:                                // Determine whether it's a path or a file
                    307:                                if (stat (kfSub->FileName, &statStruct) != 0)
                    308:                                {
1.1.1.6   root      309:                                        handleWin32Error (MainDlg);
1.1       root      310:                                        Error ("ERR_PROCESS_KEYFILE");
                    311:                                        status = FALSE;
                    312:                                        continue;
                    313:                                }
                    314:                                else if (statStruct.st_mode & S_IFDIR)          // If it's a directory
                    315:                                {
                    316:                                        // Prevent recursive folder scanning
                    317:                                        continue;        
                    318:                                }
                    319: 
1.1.1.13! root      320:                                ++keyfileCount;
1.1       root      321: 
                    322:                                // Apply keyfile to the pool
1.1.1.6   root      323:                                if (!KeyFileProcess (keyPool, kfSub))
1.1       root      324:                                {
1.1.1.6   root      325:                                        handleWin32Error (MainDlg);
1.1       root      326:                                        Error ("ERR_PROCESS_KEYFILE");
                    327:                                        status = FALSE;
                    328:                                }
                    329: 
                    330:                        } while (_findnext (searchHandle, &fBuf) != -1);
                    331:                        _findclose (searchHandle);
                    332: 
                    333:                        burn (&kfSubStruct, sizeof (kfSubStruct));
                    334: 
1.1.1.13! root      335:                        if (keyfileCount == 0)
        !           336:                        {
        !           337:                                ErrorDirect ((wstring (GetString ("ERR_KEYFILE_PATH_EMPTY")) + L"\n\n" + SingleStringToWide (kf->FileName)).c_str());
        !           338:                                status = FALSE;
        !           339:                        }
1.1       root      340:                }
                    341:                // Apply keyfile to the pool
1.1.1.6   root      342:                else if (!KeyFileProcess (keyPool, kf))
1.1       root      343:                {
1.1.1.6   root      344:                        handleWin32Error (MainDlg);
1.1       root      345:                        Error ("ERR_PROCESS_KEYFILE");
                    346:                        status = FALSE;
                    347:                }
                    348:        }
                    349: 
                    350:        /* Mix the keyfile pool contents into the password */
                    351: 
1.1.1.10  root      352:        for (i = 0; i < sizeof (keyPool); i++)
1.1       root      353:        {
                    354:                if (i < password->Length)
                    355:                        password->Text[i] += keyPool[i];
                    356:                else
                    357:                        password->Text[i] = keyPool[i];
                    358:        }
                    359: 
                    360:        if (password->Length < (int)sizeof (keyPool))
                    361:         password->Length = sizeof (keyPool);
                    362: 
                    363:        burn (keyPool, sizeof (keyPool));
                    364: 
                    365:        return status;
                    366: }
                    367: 
                    368: 
                    369: static void LoadKeyList (HWND hwndDlg, KeyFile *firstKeyFile)
                    370: {
                    371:        KeyFile *kf;
                    372:        LVITEM LvItem;
                    373:        int line = 0;
                    374:        HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
                    375: 
                    376:        ListView_DeleteAllItems (hList);
                    377:        EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE), FALSE);
                    378:        EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVEALL), firstKeyFile != NULL);
                    379:        SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, firstKeyFile != NULL);
                    380: 
                    381:        for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
                    382:        {
                    383:                memset (&LvItem,0,sizeof(LvItem));
                    384:                LvItem.mask = LVIF_TEXT|LVIF_PARAM;
                    385:                LvItem.iItem = line++;
                    386:                LvItem.iSubItem = 0;
                    387:                LvItem.pszText = kf->FileName;
                    388:                LvItem.lParam = (LPARAM) kf;
                    389:                SendMessage (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
                    390:        }
                    391: }
                    392: 
                    393: #if KEYFILE_POOL_SIZE % 4 != 0
                    394: #error KEYFILE_POOL_SIZE must be a multiple of 4
                    395: #endif
                    396: 
1.1.1.6   root      397: BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1       root      398: {
                    399:        static KeyFilesDlgParam *param;
                    400:        static KeyFilesDlgParam origParam;
                    401: 
                    402:        WORD lw = LOWORD (wParam);
                    403: 
                    404:        switch (msg)
                    405:        {
                    406:        case WM_INITDIALOG:
                    407:                {
1.1.1.2   root      408:                        LVCOLUMNW LvCol;
1.1       root      409:                        HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
                    410: 
                    411:                        param = (KeyFilesDlgParam *) lParam;
                    412:                        origParam = *(KeyFilesDlgParam *) lParam;
                    413: 
                    414:                        param->FirstKeyFile = KeyFileCloneAll (param->FirstKeyFile);
                    415: 
                    416:                        LocalizeDialog (hwndDlg, "IDD_KEYFILES");
                    417:                        DragAcceptFiles (hwndDlg, TRUE);
                    418: 
1.1.1.2   root      419:                        SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
1.1       root      420:                                LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP
                    421:                                ); 
                    422: 
                    423:                        memset (&LvCol,0,sizeof(LvCol));               
                    424:                        LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;  
1.1.1.2   root      425:                        LvCol.pszText = GetString ("KEYFILE");                           
1.1.1.9   root      426:                        LvCol.cx = CompensateXDPI (374);
1.1       root      427:                        LvCol.fmt = LVCFMT_LEFT;
1.1.1.2   root      428:                        SendMessageW (hList, LVM_INSERTCOLUMNW, 0, (LPARAM)&LvCol);
1.1       root      429: 
                    430:                        LoadKeyList (hwndDlg, param->FirstKeyFile);
                    431:                        SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, param->EnableKeyFiles);
                    432: 
1.1.1.9   root      433:                        SetWindowTextW(GetDlgItem(hwndDlg, IDT_KEYFILES_NOTE), GetString ("KEYFILES_NOTE"));
1.1.1.5   root      434: 
                    435:                        ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_INFO);
1.1       root      436:                }
                    437:                return 1;
                    438: 
                    439:        case WM_COMMAND:
                    440: 
                    441:                if (lw == IDC_KEYADD)
                    442:                {
1.1.1.9   root      443:                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1.1.4   root      444:                        if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
1.1       root      445:                        {
1.1.1.3   root      446:                                do
                    447:                                {
                    448:                                        param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    449:                                        LoadKeyList (hwndDlg, param->FirstKeyFile);
                    450: 
1.1.1.9   root      451:                                        kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1.1.3   root      452:                                } while (SelectMultipleFilesNext (kf->FileName));
1.1       root      453:                        }
1.1.1.3   root      454: 
                    455:                        free (kf);
1.1       root      456:                        return 1;
                    457:                }
                    458: 
                    459:                if (lw == IDC_ADD_KEYFILE_PATH)
                    460:                {
1.1.1.9   root      461:                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1       root      462: 
                    463:                        if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
                    464:                        {
                    465:                                param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    466:                                LoadKeyList (hwndDlg, param->FirstKeyFile);
                    467:                        }
                    468:                        else
                    469:                        {
                    470:                                free (kf);
                    471:                        }
                    472:                        return 1;
                    473:                }
                    474: 
1.1.1.9   root      475:                if (lw == IDC_TOKEN_FILES_ADD)
                    476:                {
                    477:                        list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
                    478:                        if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
                    479:                        {
                    480:                                foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
                    481:                                {
                    482:                                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
                    483:                                        strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
                    484: 
                    485:                                        param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    486:                                        LoadKeyList (hwndDlg, param->FirstKeyFile);
                    487:                                }
                    488:                        }
                    489: 
                    490:                        return 1;
                    491:                }
                    492: 
1.1       root      493:                if (lw == IDC_KEYREMOVE)
                    494:                {
                    495:                        HWND list = GetDlgItem (hwndDlg, IDC_KEYLIST);
                    496:                        LVITEM LvItem;
                    497:                        memset (&LvItem, 0, sizeof(LvItem));
                    498:                        LvItem.mask = LVIF_PARAM;   
                    499:                        LvItem.iItem = -1;
                    500: 
                    501:                        while (-1 != (LvItem.iItem = ListView_GetNextItem (list, LvItem.iItem, LVIS_SELECTED)))
                    502:                        {
                    503:                                ListView_GetItem (list, &LvItem);
                    504:                                param->FirstKeyFile = KeyFileRemove (param->FirstKeyFile, (KeyFile *) LvItem.lParam);
                    505:                        } 
                    506:                        
                    507:                        LoadKeyList (hwndDlg, param->FirstKeyFile);
                    508:                        return 1;
                    509:                }
                    510: 
                    511:                if (lw == IDC_KEYREMOVEALL)
                    512:                {
                    513:                        KeyFileRemoveAll (&param->FirstKeyFile);
                    514:                        LoadKeyList (hwndDlg, NULL);
                    515:                        return 1;
                    516:                }
                    517: 
                    518:                if (lw == IDC_GENERATE_KEYFILE)
                    519:                {
                    520:                        DialogBoxParamW (hInst, 
                    521:                                MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg,
                    522:                                (DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0);
                    523:                        return 1;
                    524:                }
                    525: 
1.1.1.5   root      526:                if (lw == IDC_LINK_KEYFILES_INFO)
                    527:                {
                    528:                        Applink ("keyfiles", TRUE, "");
                    529:                }
                    530: 
1.1       root      531:                if (lw == IDOK)
                    532:                {
                    533:                        param->EnableKeyFiles = IsButtonChecked (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE));
                    534:                        EndDialog (hwndDlg, IDOK);
                    535:                        return 1;
                    536:                }
                    537: 
                    538:                if (lw == IDCANCEL)
                    539:                {
                    540:                        KeyFileRemoveAll (&param->FirstKeyFile);
                    541:                        *param = origParam;
                    542: 
                    543:                        EndDialog (hwndDlg, IDCLOSE);
                    544:                        return 1;
                    545:                }
                    546: 
                    547:        case WM_DROPFILES:
                    548:                {
                    549:                        HDROP hdrop = (HDROP) wParam;
                    550: 
1.1.1.12  root      551:                        int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
1.1       root      552: 
                    553:                        while (count-- > 0)
                    554:                        {
1.1.1.9   root      555:                                KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1       root      556:                                DragQueryFile (hdrop, i++, kf->FileName, sizeof (kf->FileName));
                    557:                                param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    558:                                LoadKeyList (hwndDlg, param->FirstKeyFile);
                    559:                        }
                    560: 
                    561:                        DragFinish (hdrop);
                    562:                }
                    563:                return 1;
                    564: 
                    565:        case WM_NOTIFY:
                    566:                if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
                    567:                {
                    568:                        EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE),
                    569:                                ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_KEYLIST), -1, LVIS_SELECTED) != -1);
                    570:                        return 1;
                    571:                }
                    572:                break;
                    573: 
                    574:        case WM_CLOSE:
                    575:                KeyFileRemoveAll (&param->FirstKeyFile);
                    576:                *param = origParam;
                    577: 
                    578:                EndDialog (hwndDlg, IDCLOSE);
                    579:                return 1;
                    580: 
                    581:                break;
                    582: 
                    583:        }
                    584: 
                    585:        return 0;
                    586: }
                    587: 
                    588: 
1.1.1.9   root      589: #define IDM_KEYFILES_POPUP_ADD_FILES           9001
                    590: #define IDM_KEYFILES_POPUP_ADD_DIR                     9002
                    591: #define IDM_KEYFILES_POPUP_ADD_TOKEN_FILES     9003
                    592: 
                    593: BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *param)
                    594: {
                    595:        HMENU popup = CreatePopupMenu ();
                    596:        int sel;
                    597:        BOOL status = FALSE;
                    598: 
                    599:        AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_FILES, GetString ("IDC_KEYADD"));
                    600:        AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_DIR, GetString ("IDC_ADD_KEYFILE_PATH"));
                    601:        AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_TOKEN_FILES, GetString ("IDC_TOKEN_FILES_ADD"));
                    602: 
                    603:        sel = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, popupPosition.x, popupPosition.y, 0, hwndDlg, NULL);
                    604: 
                    605:        switch (sel)
                    606:        {
                    607:        case IDM_KEYFILES_POPUP_ADD_FILES:
                    608:                {
                    609:                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
                    610:                        if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
                    611:                        {
                    612:                                do
                    613:                                {
                    614:                                        param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    615:                                        kf = (KeyFile *) malloc (sizeof (KeyFile));
                    616:                                } while (SelectMultipleFilesNext (kf->FileName));
                    617: 
                    618:                                param->EnableKeyFiles = TRUE;
                    619:                                status = TRUE;
                    620:                        }
                    621: 
                    622:                        free (kf);
                    623:                }
                    624:                break;
                    625: 
                    626:        case IDM_KEYFILES_POPUP_ADD_DIR:
                    627:                {
                    628:                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
                    629: 
                    630:                        if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
                    631:                        {
                    632:                                param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    633:                                param->EnableKeyFiles = TRUE;
                    634:                                status = TRUE;
                    635:                        }
                    636:                        else
                    637:                        {
                    638:                                free (kf);
                    639:                        }
                    640:                }
                    641:                break;
                    642: 
                    643:        case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES:
                    644:                {
                    645:                        list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
                    646:                        if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
                    647:                        {
                    648:                                foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
                    649:                                {
                    650:                                        KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
                    651:                                        strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
                    652: 
                    653:                                        param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
                    654:                                        param->EnableKeyFiles = TRUE;
                    655:                                        status = TRUE;
                    656:                                }
                    657:                        }
                    658:                }
                    659:                break;
                    660:        }
                    661: 
                    662:        DestroyMenu (popup);
                    663:        return status;
                    664: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.