comparison src/os_mswin.c @ 16196:973070a30381 v8.1.1103

patch 8.1.1103: MS-Windows: old API calls are no longer needed commit https://github.com/vim/vim/commit/0eb035c974c47e65d32439b48e5a056b370ad429 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 2 22:15:55 2019 +0200 patch 8.1.1103: MS-Windows: old API calls are no longer needed Problem: MS-Windows: old API calls are no longer needed. Solution: Always use the wide functions. (Ken Takata, closes https://github.com/vim/vim/issues/4199)
author Bram Moolenaar <Bram@vim.org>
date Tue, 02 Apr 2019 22:30:04 +0200
parents cd5c83115ec6
children b3bc3ba07bef
comparison
equal deleted inserted replaced
16195:4d55a37f8b1b 16196:973070a30381
103 typedef int LPWSTR; 103 typedef int LPWSTR;
104 typedef int LRESULT; 104 typedef int LRESULT;
105 typedef int MOUSE_EVENT_RECORD; 105 typedef int MOUSE_EVENT_RECORD;
106 typedef int NEWTEXTMETRICW; 106 typedef int NEWTEXTMETRICW;
107 typedef int PACL; 107 typedef int PACL;
108 typedef int PRINTDLG; 108 typedef int PRINTDLGW;
109 typedef int PSECURITY_DESCRIPTOR; 109 typedef int PSECURITY_DESCRIPTOR;
110 typedef int PSID; 110 typedef int PSID;
111 typedef int SECURITY_INFORMATION; 111 typedef int SECURITY_INFORMATION;
112 typedef int SHORT; 112 typedef int SHORT;
113 typedef int SMALL_RECT; 113 typedef int SMALL_RECT;
280 # ifdef FEAT_GUI_MSWIN 280 # ifdef FEAT_GUI_MSWIN
281 gui_mch_settitle(title, icon); 281 gui_mch_settitle(title, icon);
282 # else 282 # else
283 if (title != NULL) 283 if (title != NULL)
284 { 284 {
285 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 285 WCHAR *wp = enc_to_utf16(title, NULL);
286 { 286
287 /* Convert the title from 'encoding' to the active codepage. */ 287 if (wp == NULL)
288 WCHAR *wp = enc_to_utf16(title, NULL); 288 return;
289 289
290 if (wp != NULL) 290 SetConsoleTitleW(wp);
291 { 291 vim_free(wp);
292 SetConsoleTitleW(wp); 292 return;
293 vim_free(wp);
294 return;
295 }
296 }
297 SetConsoleTitle((LPCSTR)title);
298 } 293 }
299 # endif 294 # endif
300 } 295 }
301 296
302 297
357 if (*fname == NUL) /* Borland behaves badly here - make it consistent */ 352 if (*fname == NUL) /* Borland behaves badly here - make it consistent */
358 nResult = mch_dirname(buf, len); 353 nResult = mch_dirname(buf, len);
359 else 354 else
360 #endif 355 #endif
361 { 356 {
362 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 357 WCHAR *wname;
358 WCHAR wbuf[MAX_PATH];
359 char_u *cname = NULL;
360
361 wname = enc_to_utf16(fname, NULL);
362 if (wname != NULL && _wfullpath(wbuf, wname, MAX_PATH) != NULL)
363 { 363 {
364 WCHAR *wname; 364 cname = utf16_to_enc((short_u *)wbuf, NULL);
365 WCHAR wbuf[MAX_PATH]; 365 if (cname != NULL)
366 char_u *cname = NULL;
367
368 /* Use the wide function:
369 * - convert the fname from 'encoding' to UCS2.
370 * - invoke _wfullpath()
371 * - convert the result from UCS2 to 'encoding'.
372 */
373 wname = enc_to_utf16(fname, NULL);
374 if (wname != NULL && _wfullpath(wbuf, wname, MAX_PATH) != NULL)
375 { 366 {
376 cname = utf16_to_enc((short_u *)wbuf, NULL); 367 vim_strncpy(buf, cname, len - 1);
377 if (cname != NULL) 368 nResult = OK;
378 {
379 vim_strncpy(buf, cname, len - 1);
380 nResult = OK;
381 }
382 } 369 }
383 vim_free(wname);
384 vim_free(cname);
385 } 370 }
386 if (nResult == FAIL) /* fall back to non-wide function */ 371 vim_free(wname);
387 { 372 vim_free(cname);
388 if (_fullpath((char *)buf, (const char *)fname, len - 1) == NULL)
389 {
390 /* failed, use relative path name */
391 vim_strncpy(buf, fname, len - 1);
392 }
393 else
394 nResult = OK;
395 }
396 } 373 }
397 374
398 #ifdef USE_FNAME_CASE 375 #ifdef USE_FNAME_CASE
399 fname_case(buf, len); 376 fname_case(buf, len);
400 #else 377 #else
476 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) 453 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
477 # define OPEN_OH_ARGTYPE intptr_t 454 # define OPEN_OH_ARGTYPE intptr_t
478 #else 455 #else
479 # define OPEN_OH_ARGTYPE long 456 # define OPEN_OH_ARGTYPE long
480 #endif 457 #endif
481
482 static int
483 stat_symlink_aware(const char *name, stat_T *stp)
484 {
485 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
486 /* Work around for VC12 or earlier (and MinGW). stat() can't handle
487 * symlinks properly.
488 * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves
489 * status of a symlink itself.
490 * VC10: stat() supports a symlink to a normal file, but it doesn't support
491 * a symlink to a directory (always returns an error).
492 * VC11 and VC12: stat() doesn't return an error for a symlink to a
493 * directory, but it doesn't set S_IFDIR flag.
494 * MinGW: Same as VC9. */
495 WIN32_FIND_DATA findData;
496 HANDLE hFind, h;
497 DWORD attr = 0;
498 BOOL is_symlink = FALSE;
499
500 hFind = FindFirstFile(name, &findData);
501 if (hFind != INVALID_HANDLE_VALUE)
502 {
503 attr = findData.dwFileAttributes;
504 if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
505 && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
506 is_symlink = TRUE;
507 FindClose(hFind);
508 }
509 if (is_symlink)
510 {
511 h = CreateFile(name, FILE_READ_ATTRIBUTES,
512 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
513 OPEN_EXISTING,
514 (attr & FILE_ATTRIBUTE_DIRECTORY)
515 ? FILE_FLAG_BACKUP_SEMANTICS : 0,
516 NULL);
517 if (h != INVALID_HANDLE_VALUE)
518 {
519 int fd, n;
520
521 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY);
522 n = _fstat(fd, (struct _stat *)stp);
523 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
524 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
525 _close(fd);
526 return n;
527 }
528 }
529 #endif
530 return stat(name, stp);
531 }
532 458
533 static int 459 static int
534 wstat_symlink_aware(const WCHAR *name, stat_T *stp) 460 wstat_symlink_aware(const WCHAR *name, stat_T *stp)
535 { 461 {
536 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) 462 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
591 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which 517 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which
592 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is 518 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is
593 * UTF-8. */ 519 * UTF-8. */
594 char_u buf[_MAX_PATH * 3 + 1]; 520 char_u buf[_MAX_PATH * 3 + 1];
595 char_u *p; 521 char_u *p;
522 WCHAR *wp;
523 int n;
596 524
597 vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); 525 vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1);
598 p = buf + STRLEN(buf); 526 p = buf + STRLEN(buf);
599 if (p > buf) 527 if (p > buf)
600 MB_PTR_BACK(buf, p); 528 MB_PTR_BACK(buf, p);
612 p = vim_strpbrk(p + 1, (char_u *)"\\/"); 540 p = vim_strpbrk(p + 1, (char_u *)"\\/");
613 if (p == NULL) 541 if (p == NULL)
614 STRCAT(buf, "\\"); 542 STRCAT(buf, "\\");
615 } 543 }
616 } 544 }
617 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 545
618 { 546 wp = enc_to_utf16(buf, NULL);
619 WCHAR *wp = enc_to_utf16(buf, NULL); 547 if (wp == NULL)
620 int n; 548 return -1;
621 549
622 if (wp != NULL) 550 n = wstat_symlink_aware(wp, stp);
623 { 551 vim_free(wp);
624 n = wstat_symlink_aware(wp, stp); 552 return n;
625 vim_free(wp);
626 return n;
627 }
628 }
629 return stat_symlink_aware((char *)buf, stp);
630 } 553 }
631 554
632 #if defined(FEAT_GUI_MSWIN) || defined(PROTO) 555 #if defined(FEAT_GUI_MSWIN) || defined(PROTO)
633 void 556 void
634 mch_settmode(int tmode UNUSED) 557 mch_settmode(int tmode UNUSED)
756 * Returning 0 implies success; -1 implies failure. 679 * Returning 0 implies success; -1 implies failure.
757 */ 680 */
758 int 681 int
759 mch_chdir(char *path) 682 mch_chdir(char *path)
760 { 683 {
684 WCHAR *p;
685 int n;
686
761 if (path[0] == NUL) /* just checking... */ 687 if (path[0] == NUL) /* just checking... */
762 return -1; 688 return -1;
763 689
764 if (p_verbose >= 5) 690 if (p_verbose >= 5)
765 { 691 {
777 } 703 }
778 704
779 if (*path == NUL) /* drive name only */ 705 if (*path == NUL) /* drive name only */
780 return 0; 706 return 0;
781 707
782 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 708 p = enc_to_utf16((char_u *)path, NULL);
783 { 709 if (p == NULL)
784 WCHAR *p = enc_to_utf16((char_u *)path, NULL); 710 return -1;
785 int n; 711
786 712 n = _wchdir(p);
787 if (p != NULL) 713 vim_free(p);
788 { 714 return n;
789 n = _wchdir(p);
790 vim_free(p);
791 return n;
792 }
793 }
794
795 return chdir(path); /* let the normal chdir() do the rest */
796 } 715 }
797 716
798 717
799 #ifdef FEAT_GUI_MSWIN 718 #ifdef FEAT_GUI_MSWIN
800 /* 719 /*
1095 /*================================================================= 1014 /*=================================================================
1096 * Win32 printer stuff 1015 * Win32 printer stuff
1097 */ 1016 */
1098 1017
1099 static HFONT prt_font_handles[2][2][2]; 1018 static HFONT prt_font_handles[2][2][2];
1100 static PRINTDLG prt_dlg; 1019 static PRINTDLGW prt_dlg;
1101 static const int boldface[2] = {FW_REGULAR, FW_BOLD}; 1020 static const int boldface[2] = {FW_REGULAR, FW_BOLD};
1102 static TEXTMETRIC prt_tm; 1021 static TEXTMETRIC prt_tm;
1103 static int prt_line_height; 1022 static int prt_line_height;
1104 static int prt_number_width; 1023 static int prt_number_width;
1105 static int prt_left_margin; 1024 static int prt_left_margin;
1117 #define IDC_PROGRESS 403 1036 #define IDC_PROGRESS 403
1118 1037
1119 static BOOL 1038 static BOOL
1120 vimSetDlgItemText(HWND hDlg, int nIDDlgItem, char_u *s) 1039 vimSetDlgItemText(HWND hDlg, int nIDDlgItem, char_u *s)
1121 { 1040 {
1122 WCHAR *wp = NULL; 1041 WCHAR *wp;
1123 BOOL ret; 1042 BOOL ret;
1124 1043
1125 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 1044 wp = enc_to_utf16(s, NULL);
1126 wp = enc_to_utf16(s, NULL); 1045 if (wp == NULL)
1127 if (wp != NULL) 1046 return FALSE;
1128 { 1047
1129 ret = SetDlgItemTextW(hDlg, nIDDlgItem, wp); 1048 ret = SetDlgItemTextW(hDlg, nIDDlgItem, wp);
1130 vim_free(wp); 1049 vim_free(wp);
1131 return ret; 1050 return ret;
1132 }
1133 return SetDlgItemText(hDlg, nIDDlgItem, (LPCSTR)s);
1134 } 1051 }
1135 1052
1136 /* 1053 /*
1137 * Convert BGR to RGB for Windows GDI calls 1054 * Convert BGR to RGB for Windows GDI calls
1138 */ 1055 */
1246 LPARAM lParam // message parameter 1163 LPARAM lParam // message parameter
1247 ) 1164 )
1248 { 1165 {
1249 HWND hwndOwner; 1166 HWND hwndOwner;
1250 RECT rc, rcDlg, rcOwner; 1167 RECT rc, rcDlg, rcOwner;
1251 PRINTDLG *pPD; 1168 PRINTDLGW *pPD;
1252 1169
1253 if (uiMsg == WM_INITDIALOG) 1170 if (uiMsg == WM_INITDIALOG)
1254 { 1171 {
1255 // Get the owner window and dialog box rectangles. 1172 // Get the owner window and dialog box rectangles.
1256 if ((hwndOwner = GetParent(hDlg)) == NULL) 1173 if ((hwndOwner = GetParent(hDlg)) == NULL)
1278 rcOwner.top + (rc.bottom / 2), 1195 rcOwner.top + (rc.bottom / 2),
1279 0, 0, // ignores size arguments 1196 0, 0, // ignores size arguments
1280 SWP_NOSIZE); 1197 SWP_NOSIZE);
1281 1198
1282 /* tackle the printdlg copiesctrl problem */ 1199 /* tackle the printdlg copiesctrl problem */
1283 pPD = (PRINTDLG *)lParam; 1200 pPD = (PRINTDLGW *)lParam;
1284 pPD->nCopies = (WORD)pPD->lCustData; 1201 pPD->nCopies = (WORD)pPD->lCustData;
1285 SetDlgItemInt( hDlg, edt3, pPD->nCopies, FALSE ); 1202 SetDlgItemInt( hDlg, edt3, pPD->nCopies, FALSE );
1286 /* Bring the window to top */ 1203 /* Bring the window to top */
1287 BringWindowToTop(GetParent(hDlg)); 1204 BringWindowToTop(GetParent(hDlg));
1288 SetForegroundWindow(hDlg); 1205 SetForegroundWindow(hDlg);
1421 LOGFONTW fLogFont; 1338 LOGFONTW fLogFont;
1422 int pifItalic; 1339 int pifItalic;
1423 int pifBold; 1340 int pifBold;
1424 int pifUnderline; 1341 int pifUnderline;
1425 1342
1426 DEVMODE *mem; 1343 DEVMODEW *mem;
1427 DEVNAMES *devname; 1344 DEVNAMES *devname;
1428 int i; 1345 int i;
1429 1346
1430 bUserAbort = &(psettings->user_abort); 1347 bUserAbort = &(psettings->user_abort);
1431 vim_memset(&prt_dlg, 0, sizeof(PRINTDLG)); 1348 vim_memset(&prt_dlg, 0, sizeof(PRINTDLGW));
1432 prt_dlg.lStructSize = sizeof(PRINTDLG); 1349 prt_dlg.lStructSize = sizeof(PRINTDLGW);
1433 #ifndef FEAT_GUI 1350 #ifndef FEAT_GUI
1434 GetConsoleHwnd(); /* get value of s_hwnd */ 1351 GetConsoleHwnd(); /* get value of s_hwnd */
1435 #endif 1352 #endif
1436 prt_dlg.hwndOwner = s_hwnd; 1353 prt_dlg.hwndOwner = s_hwnd;
1437 prt_dlg.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC; 1354 prt_dlg.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC;
1468 if (*p_pdev != NUL) 1385 if (*p_pdev != NUL)
1469 prt_dlg.hDC = CreateDC(NULL, (LPCSTR)p_pdev, NULL, NULL); 1386 prt_dlg.hDC = CreateDC(NULL, (LPCSTR)p_pdev, NULL, NULL);
1470 else 1387 else
1471 { 1388 {
1472 prt_dlg.Flags |= PD_RETURNDEFAULT; 1389 prt_dlg.Flags |= PD_RETURNDEFAULT;
1473 if (PrintDlg(&prt_dlg) == 0) 1390 if (PrintDlgW(&prt_dlg) == 0)
1474 goto init_fail_dlg; 1391 goto init_fail_dlg;
1475 } 1392 }
1476 } 1393 }
1477 else if (PrintDlg(&prt_dlg) == 0) 1394 else if (PrintDlgW(&prt_dlg) == 0)
1478 goto init_fail_dlg; 1395 goto init_fail_dlg;
1479 else 1396 else
1480 { 1397 {
1481 /* 1398 /*
1482 * keep the previous driver context 1399 * keep the previous driver context
1508 /* 1425 /*
1509 * On some windows systems the nCopies parameter is not 1426 * On some windows systems the nCopies parameter is not
1510 * passed back correctly. It must be retrieved from the 1427 * passed back correctly. It must be retrieved from the
1511 * hDevMode struct. 1428 * hDevMode struct.
1512 */ 1429 */
1513 mem = (DEVMODE *)GlobalLock(prt_dlg.hDevMode); 1430 mem = (DEVMODEW *)GlobalLock(prt_dlg.hDevMode);
1514 if (mem != NULL) 1431 if (mem != NULL)
1515 { 1432 {
1516 if (mem->dmCopies != 1) 1433 if (mem->dmCopies != 1)
1517 stored_nCopies = mem->dmCopies; 1434 stored_nCopies = mem->dmCopies;
1518 if ((mem->dmFields & DM_DUPLEX) && (mem->dmDuplex & ~DMDUP_SIMPLEX)) 1435 if ((mem->dmFields & DM_DUPLEX) && (mem->dmDuplex & ~DMDUP_SIMPLEX))
1523 GlobalUnlock(prt_dlg.hDevMode); 1440 GlobalUnlock(prt_dlg.hDevMode);
1524 1441
1525 devname = (DEVNAMES *)GlobalLock(prt_dlg.hDevNames); 1442 devname = (DEVNAMES *)GlobalLock(prt_dlg.hDevNames);
1526 if (devname != 0) 1443 if (devname != 0)
1527 { 1444 {
1528 char_u *printer_name = (char_u *)devname + devname->wDeviceOffset; 1445 WCHAR *wprinter_name = (WCHAR *)devname + devname->wDeviceOffset;
1529 char_u *port_name = (char_u *)devname +devname->wOutputOffset; 1446 WCHAR *wport_name = (WCHAR *)devname + devname->wOutputOffset;
1530 char_u *text = (char_u *)_("to %s on %s"); 1447 char_u *text = (char_u *)_("to %s on %s");
1531 char_u *printer_name_orig = printer_name; 1448 char_u *printer_name = utf16_to_enc(wprinter_name, NULL);
1532 char_u *port_name_orig = port_name; 1449 char_u *port_name = utf16_to_enc(wport_name, NULL);
1533 1450
1534 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 1451 if (printer_name != NULL && port_name != NULL)
1535 { 1452 prt_name = alloc((unsigned)(STRLEN(printer_name)
1536 char_u *to_free = NULL; 1453 + STRLEN(port_name) + STRLEN(text)));
1537 int maxlen;
1538
1539 acp_to_enc(printer_name, (int)STRLEN(printer_name), &to_free,
1540 &maxlen);
1541 if (to_free != NULL)
1542 printer_name = to_free;
1543 acp_to_enc(port_name, (int)STRLEN(port_name), &to_free, &maxlen);
1544 if (to_free != NULL)
1545 port_name = to_free;
1546 }
1547 prt_name = alloc((unsigned)(STRLEN(printer_name) + STRLEN(port_name)
1548 + STRLEN(text)));
1549 if (prt_name != NULL) 1454 if (prt_name != NULL)
1550 wsprintf((char *)prt_name, (const char *)text, 1455 wsprintf((char *)prt_name, (const char *)text,
1551 printer_name, port_name); 1456 printer_name, port_name);
1552 if (printer_name != printer_name_orig) 1457 vim_free(printer_name);
1553 vim_free(printer_name); 1458 vim_free(port_name);
1554 if (port_name != port_name_orig)
1555 vim_free(port_name);
1556 } 1459 }
1557 GlobalUnlock(prt_dlg.hDevNames); 1460 GlobalUnlock(prt_dlg.hDevNames);
1558 1461
1559 /* 1462 /*
1560 * Initialise the font according to 'printfont' 1463 * Initialise the font according to 'printfont'
1637 1540
1638 1541
1639 int 1542 int
1640 mch_print_begin(prt_settings_T *psettings) 1543 mch_print_begin(prt_settings_T *psettings)
1641 { 1544 {
1642 int ret; 1545 int ret = 0;
1643 char szBuffer[300]; 1546 char szBuffer[300];
1644 WCHAR *wp = NULL; 1547 WCHAR *wp;
1645 1548
1646 hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"), 1549 hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"),
1647 prt_dlg.hwndOwner, PrintDlgProc); 1550 prt_dlg.hwndOwner, PrintDlgProc);
1648 SetAbortProc(prt_dlg.hDC, AbortProc); 1551 SetAbortProc(prt_dlg.hDC, AbortProc);
1649 wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname)); 1552 wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname));
1650 vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer); 1553 vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer);
1651 1554
1652 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 1555 wp = enc_to_utf16(psettings->jobname, NULL);
1653 wp = enc_to_utf16(psettings->jobname, NULL);
1654 if (wp != NULL) 1556 if (wp != NULL)
1655 { 1557 {
1656 DOCINFOW di; 1558 DOCINFOW di;
1657 1559
1658 vim_memset(&di, 0, sizeof(di)); 1560 vim_memset(&di, 0, sizeof(di));
1659 di.cbSize = sizeof(di); 1561 di.cbSize = sizeof(di);
1660 di.lpszDocName = wp; 1562 di.lpszDocName = wp;
1661 ret = StartDocW(prt_dlg.hDC, &di); 1563 ret = StartDocW(prt_dlg.hDC, &di);
1662 vim_free(wp); 1564 vim_free(wp);
1663 }
1664 else
1665 {
1666 DOCINFO di;
1667
1668 vim_memset(&di, 0, sizeof(di));
1669 di.cbSize = sizeof(di);
1670 di.lpszDocName = (LPCSTR)psettings->jobname;
1671 ret = StartDoc(prt_dlg.hDC, &di);
1672 } 1565 }
1673 1566
1674 #ifdef FEAT_GUI 1567 #ifdef FEAT_GUI
1675 /* Give focus back to main window (when using MDI). */ 1568 /* Give focus back to main window (when using MDI). */
1676 SetFocus(s_hwnd); 1569 SetFocus(s_hwnd);
1723 1616
1724 int 1617 int
1725 mch_print_text_out(char_u *p, int len) 1618 mch_print_text_out(char_u *p, int len)
1726 { 1619 {
1727 SIZE sz; 1620 SIZE sz;
1728 WCHAR *wp = NULL; 1621 WCHAR *wp;
1729 int wlen = len; 1622 int wlen = len;
1730 1623 int ret = FALSE;
1731 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 1624
1732 wp = enc_to_utf16(p, &wlen); 1625 wp = enc_to_utf16(p, &wlen);
1733 if (wp != NULL) 1626 if (wp == NULL)
1734 { 1627 return FALSE;
1735 int ret = FALSE; 1628
1736 1629 TextOutW(prt_dlg.hDC, prt_pos_x + prt_left_margin,
1737 TextOutW(prt_dlg.hDC, prt_pos_x + prt_left_margin, 1630 prt_pos_y + prt_top_margin, wp, wlen);
1738 prt_pos_y + prt_top_margin, wp, wlen); 1631 GetTextExtentPoint32W(prt_dlg.hDC, wp, wlen, &sz);
1739 GetTextExtentPoint32W(prt_dlg.hDC, wp, wlen, &sz); 1632 vim_free(wp);
1740 vim_free(wp);
1741 prt_pos_x += (sz.cx - prt_tm.tmOverhang);
1742 /* This is wrong when printing spaces for a TAB. */
1743 if (p[len] != NUL)
1744 {
1745 wlen = MB_PTR2LEN(p + len);
1746 wp = enc_to_utf16(p + len, &wlen);
1747 if (wp != NULL)
1748 {
1749 GetTextExtentPoint32W(prt_dlg.hDC, wp, 1, &sz);
1750 ret = (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin);
1751 vim_free(wp);
1752 }
1753 }
1754 return ret;
1755 }
1756 TextOut(prt_dlg.hDC, prt_pos_x + prt_left_margin,
1757 prt_pos_y + prt_top_margin,
1758 (LPCSTR)p, len);
1759 #ifndef FEAT_PROPORTIONAL_FONTS
1760 prt_pos_x += len * prt_tm.tmAveCharWidth;
1761 return (prt_pos_x + prt_left_margin + prt_tm.tmAveCharWidth
1762 + prt_tm.tmOverhang > prt_right_margin);
1763 #else
1764 GetTextExtentPoint32(prt_dlg.hDC, (LPCSTR)p, len, &sz);
1765 prt_pos_x += (sz.cx - prt_tm.tmOverhang); 1633 prt_pos_x += (sz.cx - prt_tm.tmOverhang);
1766 /* This is wrong when printing spaces for a TAB. */ 1634 /* This is wrong when printing spaces for a TAB. */
1767 if (p[len] == NUL) 1635 if (p[len] != NUL)
1768 return FALSE; 1636 {
1769 GetTextExtentPoint32(prt_dlg.hDC, p + len, 1, &sz); 1637 wlen = MB_PTR2LEN(p + len);
1770 return (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin); 1638 wp = enc_to_utf16(p + len, &wlen);
1771 #endif 1639 if (wp != NULL)
1640 {
1641 GetTextExtentPoint32W(prt_dlg.hDC, wp, 1, &sz);
1642 ret = (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin);
1643 vim_free(wp);
1644 }
1645 }
1646 return ret;
1772 } 1647 }
1773 1648
1774 void 1649 void
1775 mch_print_set_font(int iBold, int iItalic, int iUnderline) 1650 mch_print_set_font(int iBold, int iItalic, int iUnderline)
1776 { 1651 {
1861 char_u * 1736 char_u *
1862 resolve_reparse_point(char_u *fname) 1737 resolve_reparse_point(char_u *fname)
1863 { 1738 {
1864 HANDLE h = INVALID_HANDLE_VALUE; 1739 HANDLE h = INVALID_HANDLE_VALUE;
1865 DWORD size; 1740 DWORD size;
1741 WCHAR *p;
1866 char_u *rfname = NULL; 1742 char_u *rfname = NULL;
1867 FILE_NAME_INFO_ *nameinfo = NULL; 1743 FILE_NAME_INFO_ *nameinfo = NULL;
1868 WCHAR buff[MAX_PATH], *volnames = NULL; 1744 WCHAR buff[MAX_PATH], *volnames = NULL;
1869 HANDLE hv; 1745 HANDLE hv;
1870 DWORD snfile, snfind; 1746 DWORD snfile, snfind;
1885 if (pGetFileInformationByHandleEx == NULL || 1761 if (pGetFileInformationByHandleEx == NULL ||
1886 pGetVolumeInformationByHandleW == NULL) 1762 pGetVolumeInformationByHandleW == NULL)
1887 return NULL; 1763 return NULL;
1888 } 1764 }
1889 1765
1890 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 1766 p = enc_to_utf16(fname, NULL);
1891 { 1767 if (p == NULL)
1892 WCHAR *p; 1768 goto fail;
1893 1769
1894 p = enc_to_utf16(fname, NULL); 1770 if ((GetFileAttributesW(p) & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
1895 if (p == NULL) 1771 {
1896 goto fail;
1897
1898 if ((GetFileAttributesW(p) & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
1899 {
1900 vim_free(p);
1901 goto fail;
1902 }
1903
1904 h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING,
1905 FILE_FLAG_BACKUP_SEMANTICS, NULL);
1906 vim_free(p); 1772 vim_free(p);
1907 } 1773 goto fail;
1908 else 1774 }
1909 { 1775
1910 if ((GetFileAttributes((char*) fname) & 1776 h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING,
1911 FILE_ATTRIBUTE_REPARSE_POINT) == 0) 1777 FILE_FLAG_BACKUP_SEMANTICS, NULL);
1912 goto fail; 1778 vim_free(p);
1913
1914 h = CreateFile((char*) fname, 0, 0, NULL, OPEN_EXISTING,
1915 FILE_FLAG_BACKUP_SEMANTICS, NULL);
1916 }
1917 1779
1918 if (h == INVALID_HANDLE_VALUE) 1780 if (h == INVALID_HANDLE_VALUE)
1919 goto fail; 1781 goto fail;
1920 1782
1921 size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1); 1783 size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1);
1986 { 1848 {
1987 HRESULT hr; 1849 HRESULT hr;
1988 IShellLink *psl = NULL; 1850 IShellLink *psl = NULL;
1989 IPersistFile *ppf = NULL; 1851 IPersistFile *ppf = NULL;
1990 OLECHAR wsz[MAX_PATH]; 1852 OLECHAR wsz[MAX_PATH];
1991 WIN32_FIND_DATA ffd; // we get those free of charge
1992 CHAR buf[MAX_PATH]; // could have simply reused 'wsz'...
1993 char_u *rfname = NULL; 1853 char_u *rfname = NULL;
1994 int len; 1854 int len;
1995 IShellLinkW *pslw = NULL; 1855 IShellLinkW *pslw = NULL;
1996 WIN32_FIND_DATAW ffdw; // we get those free of charge 1856 WIN32_FIND_DATAW ffdw; // we get those free of charge
1997 1857
2003 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) 1863 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0)
2004 return rfname; 1864 return rfname;
2005 1865
2006 CoInitialize(NULL); 1866 CoInitialize(NULL);
2007 1867
2008 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
2009 {
2010 // create a link manager object and request its interface
2011 hr = CoCreateInstance(
2012 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2013 &IID_IShellLinkW, (void**)&pslw);
2014 if (hr == S_OK)
2015 {
2016 WCHAR *p = enc_to_utf16(fname, NULL);
2017
2018 if (p != NULL)
2019 {
2020 // Get a pointer to the IPersistFile interface.
2021 hr = pslw->lpVtbl->QueryInterface(
2022 pslw, &IID_IPersistFile, (void**)&ppf);
2023 if (hr != S_OK)
2024 goto shortcut_errorw;
2025
2026 // "load" the name and resolve the link
2027 hr = ppf->lpVtbl->Load(ppf, p, STGM_READ);
2028 if (hr != S_OK)
2029 goto shortcut_errorw;
2030 # if 0 // This makes Vim wait a long time if the target does not exist.
2031 hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
2032 if (hr != S_OK)
2033 goto shortcut_errorw;
2034 # endif
2035
2036 // Get the path to the link target.
2037 ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR));
2038 hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0);
2039 if (hr == S_OK && wsz[0] != NUL)
2040 rfname = utf16_to_enc(wsz, NULL);
2041
2042 shortcut_errorw:
2043 vim_free(p);
2044 goto shortcut_end;
2045 }
2046 }
2047 goto shortcut_end;
2048 }
2049 // create a link manager object and request its interface 1868 // create a link manager object and request its interface
2050 hr = CoCreateInstance( 1869 hr = CoCreateInstance(
2051 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, 1870 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2052 &IID_IShellLink, (void**)&psl); 1871 &IID_IShellLinkW, (void**)&pslw);
2053 if (hr != S_OK) 1872 if (hr == S_OK)
2054 goto shortcut_end; 1873 {
2055 1874 WCHAR *p = enc_to_utf16(fname, NULL);
2056 // Get a pointer to the IPersistFile interface. 1875
2057 hr = psl->lpVtbl->QueryInterface( 1876 if (p != NULL)
2058 psl, &IID_IPersistFile, (void**)&ppf); 1877 {
2059 if (hr != S_OK) 1878 // Get a pointer to the IPersistFile interface.
2060 goto shortcut_end; 1879 hr = pslw->lpVtbl->QueryInterface(
2061 1880 pslw, &IID_IPersistFile, (void**)&ppf);
2062 // full path string must be in Unicode. 1881 if (hr != S_OK)
2063 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)fname, -1, wsz, MAX_PATH); 1882 goto shortcut_errorw;
2064 1883
2065 // "load" the name and resolve the link 1884 // "load" the name and resolve the link
2066 hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); 1885 hr = ppf->lpVtbl->Load(ppf, p, STGM_READ);
2067 if (hr != S_OK) 1886 if (hr != S_OK)
2068 goto shortcut_end; 1887 goto shortcut_errorw;
2069 # if 0 // This makes Vim wait a long time if the target doesn't exist. 1888 # if 0 // This makes Vim wait a long time if the target does not exist.
2070 hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); 1889 hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
2071 if (hr != S_OK) 1890 if (hr != S_OK)
2072 goto shortcut_end; 1891 goto shortcut_errorw;
2073 # endif 1892 # endif
2074 1893
2075 // Get the path to the link target. 1894 // Get the path to the link target.
2076 ZeroMemory(buf, MAX_PATH); 1895 ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR));
2077 hr = psl->lpVtbl->GetPath(psl, buf, MAX_PATH, &ffd, 0); 1896 hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0);
2078 if (hr == S_OK && buf[0] != NUL) 1897 if (hr == S_OK && wsz[0] != NUL)
2079 rfname = vim_strsave((char_u *)buf); 1898 rfname = utf16_to_enc(wsz, NULL);
2080 1899
2081 shortcut_end: 1900 shortcut_errorw:
1901 vim_free(p);
1902 }
1903 }
1904
2082 // Release all interface pointers (both belong to the same object) 1905 // Release all interface pointers (both belong to the same object)
2083 if (ppf != NULL) 1906 if (ppf != NULL)
2084 ppf->lpVtbl->Release(ppf); 1907 ppf->lpVtbl->Release(ppf);
2085 if (psl != NULL) 1908 if (psl != NULL)
2086 psl->lpVtbl->Release(psl); 1909 psl->lpVtbl->Release(psl);