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

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

unix.superglobalmegacorp.com

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