src/mess/osd/winui/softwarelist.c
| r8204 | r8205 | |
| 46 | 46 | const hash_info *hashinfo; |
| 47 | 47 | |
| 48 | 48 | const char *zip_entry_name; |
| 49 | | const char *base_name; |
| 50 | | char file_name[1]; |
| 49 | char list_name[256]; |
| 50 | char description[256]; |
| 51 | char file_name[256]; |
| 52 | char publisher[256]; |
| 53 | char year[10]; |
| 51 | 54 | }; |
| 52 | 55 | |
| 53 | 56 | typedef struct _directory_search_info directory_search_info; |
| r8204 | r8205 | |
| 82 | 85 | |
| 83 | 86 | |
| 84 | 87 | |
| 85 | | //============================================================ |
| 86 | 88 | |
| 87 | | static LPCSTR NormalizePath(LPCSTR pszPath, LPSTR pszBuffer, size_t nBufferSize) |
| 88 | | { |
| 89 | | BOOL bChanged = FALSE; |
| 90 | | LPSTR s; |
| 91 | | int i, j; |
| 92 | | |
| 93 | | if (pszPath[0] == '\\') |
| 94 | | { |
| 95 | | win_get_current_directory_utf8(nBufferSize, pszBuffer); |
| 96 | | pszBuffer[2] = '\0'; |
| 97 | | bChanged = TRUE; |
| 98 | | } |
| 99 | | else if (!isalpha(pszPath[0]) || (pszPath[1] != ':')) |
| 100 | | { |
| 101 | | win_get_current_directory_utf8(nBufferSize, pszBuffer); |
| 102 | | bChanged = TRUE; |
| 103 | | } |
| 104 | | |
| 105 | | if (bChanged) |
| 106 | | { |
| 107 | | s = (LPSTR) alloca(strlen(pszBuffer) + 1); |
| 108 | | strcpy(s, pszBuffer); |
| 109 | | snprintf(pszBuffer, nBufferSize, "%s\\%s", s, pszPath); |
| 110 | | pszPath = pszBuffer; |
| 111 | | |
| 112 | | // Remove double path separators |
| 113 | | i = 0; |
| 114 | | j = 0; |
| 115 | | while(pszBuffer[i]) |
| 116 | | { |
| 117 | | while ((pszBuffer[i] == '\\') && (pszBuffer[i+1] == '\\')) |
| 118 | | i++; |
| 119 | | pszBuffer[j++] = pszBuffer[i++]; |
| 120 | | } |
| 121 | | pszBuffer[j] = '\0'; |
| 122 | | } |
| 123 | | return pszPath; |
| 124 | | } |
| 125 | | |
| 126 | | |
| 127 | | |
| 128 | 89 | static software_list_info *GetSoftwareListInfo(HWND hwndPicker) |
| 129 | 90 | { |
| 130 | 91 | HANDLE h; |
| r8204 | r8205 | |
| 363 | 324 | } |
| 364 | 325 | |
| 365 | 326 | |
| 366 | | |
| 367 | | static BOOL SoftwareList_AddFileEntry(HWND hwndPicker, LPCSTR pszFilename, |
| 368 | | UINT nZipEntryNameLength, UINT32 nCrc, BOOL bForce) |
| 327 | BOOL SoftwareList_AddFile(HWND hwndPicker,LPCSTR pszName, LPCSTR pszListname, LPCSTR pszDescription, LPCSTR pszPublisher, LPCSTR pszYear) |
| 369 | 328 | { |
| 329 | Picker_ResetIdle(hwndPicker); |
| 330 | |
| 370 | 331 | software_list_info *pPickerInfo; |
| 371 | 332 | file_info **ppNewIndex; |
| 372 | 333 | file_info *pInfo; |
| 373 | 334 | int nIndex, nSize; |
| 374 | | LPCSTR pszExtension = NULL; |
| 335 | // LPCSTR pszExtension = NULL; |
| 375 | 336 | const device_config *device = NULL; |
| 376 | 337 | |
| 377 | 338 | // first check to see if it is already here |
| 378 | | if (SoftwareList_LookupIndex(hwndPicker, pszFilename) >= 0) |
| 339 | if (SoftwareList_LookupIndex(hwndPicker, pszName) >= 0) |
| 379 | 340 | return TRUE; |
| 380 | 341 | |
| 381 | 342 | pPickerInfo = GetSoftwareListInfo(hwndPicker); |
| 382 | 343 | |
| 383 | | // look up the device |
| 384 | | if (strrchr(pszFilename, '.')) |
| 385 | | pszExtension = strrchr(pszFilename, '.'); |
| 386 | | if ((pszExtension != NULL) && (pPickerInfo->config != NULL)) |
| 387 | | { |
| 388 | | for (device = pPickerInfo->config->mconfig->devicelist.first(); device != NULL;device = device->next) |
| 389 | | { |
| 390 | | if (is_image_device(device)) |
| 391 | | { |
| 392 | | if (image_device_uses_file_extension(device, pszExtension)) |
| 393 | | break; |
| 394 | | } |
| 395 | | } |
| 396 | | } |
| 397 | | |
| 398 | | // no device? cop out unless bForce is on |
| 399 | | if ((device == NULL) && !bForce) |
| 400 | | return TRUE; |
| 401 | | |
| 402 | 344 | // create the FileInfo structure |
| 403 | | nSize = sizeof(file_info) + strlen(pszFilename); |
| 345 | nSize = sizeof(file_info); |
| 404 | 346 | pInfo = (file_info *) malloc(nSize); |
| 405 | 347 | if (!pInfo) |
| 406 | 348 | goto error; |
| 407 | 349 | memset(pInfo, 0, nSize); |
| 408 | 350 | |
| 409 | 351 | // copy the filename |
| 410 | | strcpy(pInfo->file_name, pszFilename); |
| 352 | strcpy(pInfo->file_name, pszName); |
| 353 | strcpy(pInfo->list_name, pszListname); |
| 354 | strcpy(pInfo->description, pszDescription); |
| 355 | strcpy(pInfo->publisher, pszPublisher); |
| 356 | strcpy(pInfo->year, pszYear); |
| 411 | 357 | |
| 412 | 358 | // set up device and CRC, if specified |
| 413 | 359 | pInfo->device = device; |
| 414 | | if ((device != NULL) && (image_device_getinfo(pPickerInfo->config->mconfig, device).has_partial_hash != 0)) |
| 415 | | nCrc = 0; |
| 416 | | if (nCrc != 0) |
| 417 | | snprintf(pInfo->hash_string, ARRAY_LENGTH(pInfo->hash_string), "c:%08x#", nCrc); |
| 418 | | |
| 419 | | // set up zip entry name length, if specified |
| 420 | | if (nZipEntryNameLength > 0) |
| 421 | | pInfo->zip_entry_name = pInfo->file_name + strlen(pInfo->file_name) - nZipEntryNameLength; |
| 422 | | |
| 423 | | // calculate the subname |
| 424 | | pInfo->base_name = strrchr(pInfo->file_name, '\\'); |
| 425 | | if (pInfo->base_name) |
| 426 | | pInfo->base_name++; |
| 427 | | else |
| 428 | | pInfo->base_name = pInfo->file_name; |
| 429 | | |
| 360 | |
| 430 | 361 | ppNewIndex = (file_info**)malloc((pPickerInfo->file_index_length + 1) * sizeof(*pPickerInfo->file_index)); |
| 431 | 362 | memcpy(ppNewIndex,pPickerInfo->file_index,pPickerInfo->file_index_length * sizeof(*pPickerInfo->file_index)); |
| 432 | 363 | if (pPickerInfo->file_index) free(pPickerInfo->file_index); |
| r8204 | r8205 | |
| 447 | 378 | error: |
| 448 | 379 | if (pInfo) |
| 449 | 380 | free(pInfo); |
| 450 | | return FALSE; |
| 381 | return FALSE; |
| 451 | 382 | } |
| 452 | 383 | |
| 453 | 384 | |
| 454 | | |
| 455 | | static BOOL SoftwareList_AddZipEntFile(HWND hwndPicker, LPCSTR pszZipPath, |
| 456 | | BOOL bForce, zip_file *pZip, const zip_file_header *pZipEnt) |
| 457 | | { |
| 458 | | LPSTR s; |
| 459 | | LPCSTR temp = pZipEnt->filename; |
| 460 | | int nLength; |
| 461 | | int nZipEntryNameLength; |
| 462 | | |
| 463 | | // special case; skip first two characters if they are './' |
| 464 | | if ((pZipEnt->filename[0] == '.') && (pZipEnt->filename[1] == '/')) |
| 465 | | { |
| 466 | | while(*(++temp) == '/') |
| 467 | | ; |
| 468 | | } |
| 469 | | |
| 470 | | nZipEntryNameLength = strlen(pZipEnt->filename); |
| 471 | | nLength = strlen(pszZipPath) + 1 + nZipEntryNameLength + 1; |
| 472 | | s = (LPSTR) alloca(nLength); |
| 473 | | snprintf(s, nLength, "%s\\%s", pszZipPath, pZipEnt->filename); |
| 474 | | |
| 475 | | return SoftwareList_AddFileEntry(hwndPicker, s, |
| 476 | | nZipEntryNameLength, pZipEnt->crc, bForce); |
| 477 | | } |
| 478 | | |
| 479 | | static BOOL SoftwareList_InternalAddFile(HWND hwndPicker, LPCSTR pszFilename, |
| 480 | | BOOL bForce) |
| 481 | | { |
| 482 | | LPCSTR s; |
| 483 | | BOOL rc = TRUE; |
| 484 | | zip_error ziperr; |
| 485 | | zip_file *pZip; |
| 486 | | const zip_file_header *pZipEnt; |
| 487 | | |
| 488 | | s = strrchr(pszFilename, '.'); |
| 489 | | if (s && !mame_stricmp(s, ".zip")) |
| 490 | | { |
| 491 | | ziperr = zip_file_open(pszFilename, &pZip); |
| 492 | | if (ziperr == ZIPERR_NONE) |
| 493 | | { |
| 494 | | pZipEnt = zip_file_first_file(pZip); |
| 495 | | while(rc && pZipEnt) |
| 496 | | { |
| 497 | | rc = SoftwareList_AddZipEntFile(hwndPicker, pszFilename, |
| 498 | | bForce, pZip, pZipEnt); |
| 499 | | pZipEnt = zip_file_next_file(pZip); |
| 500 | | } |
| 501 | | zip_file_close(pZip); |
| 502 | | } |
| 503 | | } |
| 504 | | else |
| 505 | | { |
| 506 | | rc = SoftwareList_AddFileEntry(hwndPicker, pszFilename, 0, 0, bForce); |
| 507 | | } |
| 508 | | return rc; |
| 509 | | } |
| 510 | | |
| 511 | | |
| 512 | | |
| 513 | | BOOL SoftwareList_AddFile(HWND hwndPicker, LPCSTR pszFilename) |
| 514 | | { |
| 515 | | char szBuffer[MAX_PATH]; |
| 516 | | |
| 517 | | Picker_ResetIdle(hwndPicker); |
| 518 | | pszFilename = NormalizePath(pszFilename, szBuffer, sizeof(szBuffer) |
| 519 | | / sizeof(szBuffer[0])); |
| 520 | | |
| 521 | | return SoftwareList_InternalAddFile(hwndPicker, pszFilename, TRUE); |
| 522 | | } |
| 523 | | |
| 524 | | |
| 525 | | |
| 526 | | BOOL SoftwareList_AddDirectory(HWND hwndPicker, LPCSTR pszDirectory) |
| 527 | | { |
| 528 | | software_list_info *pPickerInfo; |
| 529 | | directory_search_info *pSearchInfo; |
| 530 | | directory_search_info **ppLast; |
| 531 | | size_t nSearchInfoSize; |
| 532 | | char szBuffer[MAX_PATH]; |
| 533 | | |
| 534 | | pszDirectory = NormalizePath(pszDirectory, szBuffer, sizeof(szBuffer) |
| 535 | | / sizeof(szBuffer[0])); |
| 536 | | |
| 537 | | Picker_ResetIdle(hwndPicker); |
| 538 | | pPickerInfo = GetSoftwareListInfo(hwndPicker); |
| 539 | | |
| 540 | | nSearchInfoSize = sizeof(directory_search_info) + strlen(pszDirectory); |
| 541 | | pSearchInfo = (directory_search_info *)malloc(nSearchInfoSize); |
| 542 | | if (!pSearchInfo) |
| 543 | | return FALSE; |
| 544 | | memset(pSearchInfo, 0, nSearchInfoSize); |
| 545 | | pSearchInfo->find_handle = INVALID_HANDLE_VALUE; |
| 546 | | |
| 547 | | strcpy(pSearchInfo->directory_name, pszDirectory); |
| 548 | | |
| 549 | | // insert into linked list |
| 550 | | if (pPickerInfo->last_search_info) |
| 551 | | ppLast = &pPickerInfo->last_search_info->next; |
| 552 | | else |
| 553 | | ppLast = &pPickerInfo->first_search_info; |
| 554 | | *ppLast = pSearchInfo; |
| 555 | | pPickerInfo->last_search_info = pSearchInfo; |
| 556 | | return TRUE; |
| 557 | | } |
| 558 | | |
| 559 | | |
| 560 | | |
| 561 | 385 | static void SoftwareList_FreeSearchInfo(directory_search_info *pSearchInfo) |
| 562 | 386 | { |
| 563 | 387 | if (pSearchInfo->find_handle != INVALID_HANDLE_VALUE) |
| r8204 | r8205 | |
| 601 | 425 | } |
| 602 | 426 | |
| 603 | 427 | |
| 604 | | |
| 605 | | static BOOL SoftwareList_AddEntry(HWND hwndPicker, |
| 606 | | directory_search_info *pSearchInfo) |
| 607 | | { |
| 608 | | //software_list_info *pPickerInfo; |
| 609 | | LPSTR pszFilename; |
| 610 | | BOOL rc; |
| 611 | | char* utf8_FileName; |
| 612 | | |
| 613 | | //pPickerInfo = GetSoftwareListInfo(hwndPicker); |
| 614 | | |
| 615 | | utf8_FileName = utf8_from_tstring(pSearchInfo->fd.cFileName); |
| 616 | | if( !utf8_FileName ) |
| 617 | | return FALSE; |
| 618 | | |
| 619 | | if (!strcmp(utf8_FileName, ".") || !strcmp(utf8_FileName, "..")) { |
| 620 | | osd_free(utf8_FileName); |
| 621 | | return TRUE; |
| 622 | | } |
| 623 | | |
| 624 | | pszFilename = (LPSTR)alloca(strlen(pSearchInfo->directory_name) + 1 + strlen(utf8_FileName) + 1); |
| 625 | | strcpy(pszFilename, pSearchInfo->directory_name); |
| 626 | | strcat(pszFilename, "\\"); |
| 627 | | strcat(pszFilename, utf8_FileName); |
| 628 | | |
| 629 | | if (pSearchInfo->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
| 630 | | rc = SoftwareList_AddDirectory(hwndPicker, pszFilename); |
| 631 | | else |
| 632 | | rc = SoftwareList_InternalAddFile(hwndPicker, pszFilename, FALSE); |
| 633 | | |
| 634 | | osd_free(utf8_FileName); |
| 635 | | return rc; |
| 636 | | } |
| 637 | | |
| 638 | | |
| 639 | | |
| 640 | 428 | BOOL SoftwareList_Idle(HWND hwndPicker) |
| 641 | 429 | { |
| 642 | 430 | software_list_info *pPickerInfo; |
| r8204 | r8205 | |
| 671 | 459 | |
| 672 | 460 | if (bSuccess) |
| 673 | 461 | { |
| 674 | | SoftwareList_AddEntry(hwndPicker, pSearchInfo); |
| 462 | //SoftwareList_AddEntry(hwndPicker, pSearchInfo); |
| 675 | 463 | } |
| 676 | 464 | else |
| 677 | 465 | { |
| r8204 | r8205 | |
| 733 | 521 | software_list_info *pPickerInfo; |
| 734 | 522 | const file_info *pFileInfo; |
| 735 | 523 | LPCTSTR s = NULL; |
| 736 | | const char *pszUtf8 = NULL; |
| 737 | | unsigned int nHashFunction = 0; |
| 738 | | char szBuffer[256]; |
| 739 | 524 | TCHAR* t_buf; |
| 740 | 525 | |
| 741 | 526 | pPickerInfo = GetSoftwareListInfo(hwndPicker); |
| r8204 | r8205 | |
| 747 | 532 | switch(nColumn) |
| 748 | 533 | { |
| 749 | 534 | case MESS_COLUMN_IMAGES: |
| 750 | | t_buf = tstring_from_utf8(pFileInfo->base_name); |
| 535 | t_buf = tstring_from_utf8(pFileInfo->file_name); |
| 751 | 536 | if( !t_buf ) |
| 752 | 537 | return s; |
| 753 | 538 | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 754 | 539 | s = pszBuffer; |
| 755 | 540 | osd_free(t_buf); |
| 756 | 541 | break; |
| 757 | | |
| 758 | | case MESS_COLUMN_GOODNAME: |
| 759 | | case MESS_COLUMN_MANUFACTURER: |
| 760 | | case MESS_COLUMN_YEAR: |
| 761 | | case MESS_COLUMN_PLAYABLE: |
| 762 | | if (pFileInfo->hashinfo) |
| 763 | | { |
| 764 | | switch(nColumn) |
| 765 | | { |
| 766 | | case MESS_COLUMN_GOODNAME: |
| 767 | | pszUtf8 = pFileInfo->hashinfo->longname; |
| 768 | | break; |
| 769 | | case MESS_COLUMN_MANUFACTURER: |
| 770 | | pszUtf8 = pFileInfo->hashinfo->manufacturer; |
| 771 | | break; |
| 772 | | case MESS_COLUMN_YEAR: |
| 773 | | pszUtf8 = pFileInfo->hashinfo->year; |
| 774 | | break; |
| 775 | | case MESS_COLUMN_PLAYABLE: |
| 776 | | pszUtf8 = pFileInfo->hashinfo->playable; |
| 777 | | break; |
| 778 | | } |
| 779 | | if (pszUtf8) |
| 780 | | { |
| 781 | | t_buf = tstring_from_utf8(pszUtf8); |
| 782 | | if( !t_buf ) |
| 783 | | return s; |
| 784 | | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 785 | | s = pszBuffer; |
| 786 | | osd_free(t_buf); |
| 787 | | } |
| 788 | | } |
| 542 | case 1: |
| 543 | t_buf = tstring_from_utf8(pFileInfo->list_name); |
| 544 | if( !t_buf ) |
| 545 | return s; |
| 546 | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 547 | s = pszBuffer; |
| 548 | osd_free(t_buf); |
| 789 | 549 | break; |
| 790 | | |
| 791 | | case MESS_COLUMN_CRC: |
| 792 | | case MESS_COLUMN_MD5: |
| 793 | | case MESS_COLUMN_SHA1: |
| 794 | | switch (nColumn) |
| 795 | | { |
| 796 | | case MESS_COLUMN_CRC: nHashFunction = HASH_CRC; break; |
| 797 | | case MESS_COLUMN_MD5: nHashFunction = HASH_MD5; break; |
| 798 | | case MESS_COLUMN_SHA1: nHashFunction = HASH_SHA1; break; |
| 799 | | } |
| 800 | | if (hash_data_extract_printable_checksum(pFileInfo->hash_string, nHashFunction, szBuffer)) |
| 801 | | { |
| 802 | | t_buf = tstring_from_utf8(szBuffer); |
| 803 | | if( !t_buf ) |
| 804 | | return s; |
| 805 | | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 806 | | s = pszBuffer; |
| 807 | | osd_free(t_buf); |
| 808 | | } |
| 550 | case 2: |
| 551 | t_buf = tstring_from_utf8(pFileInfo->description); |
| 552 | if( !t_buf ) |
| 553 | return s; |
| 554 | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 555 | s = pszBuffer; |
| 556 | osd_free(t_buf); |
| 809 | 557 | break; |
| 558 | case 3: |
| 559 | t_buf = tstring_from_utf8(pFileInfo->year); |
| 560 | if( !t_buf ) |
| 561 | return s; |
| 562 | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 563 | s = pszBuffer; |
| 564 | osd_free(t_buf); |
| 565 | break; |
| 566 | case 4: |
| 567 | t_buf = tstring_from_utf8(pFileInfo->publisher); |
| 568 | if( !t_buf ) |
| 569 | return s; |
| 570 | _sntprintf(pszBuffer, nBufferLength, TEXT("%s"), t_buf); |
| 571 | s = pszBuffer; |
| 572 | osd_free(t_buf); |
| 573 | break; |
| 574 | |
| 810 | 575 | } |
| 811 | 576 | return s; |
| 812 | 577 | } |