1 /**
2  * Windowsのショートカットの矢印を消すためのやつ。
3  *
4  * Author: $(LINK2 https://twitter.com/dokutoku3, dokutoku)
5  * License: $(LINK2 https://creativecommons.org/publicdomain/zero/1.0/, CC0 1.0 Universal)
6  */
7 module remove_shortcut_arrow.remove;
8 
9 
10 version (Windows):
11 
12 version (NON_WINREG) {
13 } else {
14 	version = IS_WINREG;
15 }
16 
17 private static import core.sys.windows.basetsd;
18 private static import core.sys.windows.winbase;
19 private static import core.sys.windows.windef;
20 private static import core.sys.windows.winerror;
21 private static import core.sys.windows.winnt;
22 private static import remove_shortcut_arrow.command;
23 private static import remove_shortcut_arrow.no_arrow;
24 private static import remove_shortcut_arrow.path;
25 private static import remove_shortcut_arrow.registory;
26 
27 /**
28  * プログラムのディレクトリを作成する
29  */
30 nothrow @nogc
31 private bool create_direcotry(const core.sys.windows.winnt.LPCWSTR program_path)
32 
33 	do
34 	{
35 		core.sys.windows.windef.BOOL result = core.sys.windows.winbase.CreateDirectoryW(program_path, null);
36 
37 		return (result == core.sys.windows.windef.TRUE) || (core.sys.windows.winbase.GetLastError() == core.sys.windows.winerror.ERROR_ALREADY_EXISTS);
38 	}
39 
40 /**
41  * no-arrow.icoをファイルに書き出す
42  *
43  * Params:
44  *      output_path = no-arrow.icoの絶対パス
45  */
46 nothrow @nogc
47 private bool write_no_arrow_ico(const core.sys.windows.winnt.LPCWSTR output_path)
48 
49 	do
50 	{
51 		core.sys.windows.basetsd.HANDLE hFile = core.sys.windows.winbase.CreateFileW(output_path, core.sys.windows.winnt.GENERIC_WRITE, core.sys.windows.winnt.FILE_SHARE_WRITE, null, core.sys.windows.winbase.CREATE_ALWAYS, core.sys.windows.winnt.FILE_ATTRIBUTE_NORMAL, null);
52 
53 		if (hFile == core.sys.windows.winbase.INVALID_HANDLE_VALUE) {
54 			return false;
55 		}
56 
57 		scope (exit) {
58 			core.sys.windows.winbase.CloseHandle(hFile);
59 		}
60 
61 		/* Windows7以降ではnullを渡せないので、適当なポインターを渡す*/
62 		core.sys.windows.windef.DWORD temp = void;
63 
64 		core.sys.windows.windef.BOOL result = core.sys.windows.winbase.WriteFile(hFile, &(remove_shortcut_arrow.no_arrow.ico_binary[0]), remove_shortcut_arrow.no_arrow.ico_binary.length, &temp, null);
65 
66 		return result == core.sys.windows.windef.TRUE;
67 	}
68 
69 /**
70  * ショートカットアイコンを削除する。
71  */
72 version (IS_WINREG)
73 extern (C)
74 nothrow @nogc
75 public bool remove_windows_shortcut_arrow()
76 
77 	do
78 	{
79 		remove_shortcut_arrow.path.program_path_buffer buffer = void;
80 
81 		return ((remove_shortcut_arrow.path.get_program_path(buffer)) && (.create_direcotry(&(buffer.program_path[0]))) && (.write_no_arrow_ico(&(buffer.ico_path[0]))) && (remove_shortcut_arrow.registory.add_registory(&(buffer.ico_path[0]))) && ((remove_shortcut_arrow.command.exec_clear_icon_cache()) || (true))) ? (true) : (false);
82 	}
83 
84 /**
85  * REGコマンドを利用して、レジストリにアイコンファイルを登録する。
86  */
87 extern (C)
88 nothrow @nogc
89 public bool exec_remove_windows_shortcut_arrow_command(const core.sys.windows.winnt.LPCWSTR ico_path)
90 
91 	do
92 	{
93 		//Unicode版はバッファに入れなければならない
94 		wchar[remove_shortcut_arrow.command.REG_ADD_COMMAND_BUFFER_LENGTH] command_buffer = void;
95 
96 		if (!remove_shortcut_arrow.command.copy_remove_windows_shortcut_arrow_command(command_buffer.ptr, command_buffer.length, ico_path)) {
97 			return false;
98 		}
99 
100 		return remove_shortcut_arrow.command.exec_system32_command(&(command_buffer[0]));
101 	}
102 
103 /**
104  * REGコマンドを利用して、ショートカットアイコンを削除する。
105  */
106 extern (C)
107 nothrow @nogc
108 public bool reg_remove_windows_shortcut_arrow()
109 
110 	do
111 	{
112 		remove_shortcut_arrow.path.program_path_buffer buffer = void;
113 
114 		return ((remove_shortcut_arrow.path.get_program_path(buffer)) && (.create_direcotry(&(buffer.program_path[0]))) && (.write_no_arrow_ico(&(buffer.ico_path[0]))) && (.exec_remove_windows_shortcut_arrow_command(&(buffer.ico_path[0]))) && ((remove_shortcut_arrow.command.exec_clear_icon_cache()) || (true))) ? (true) : (false);
115 	}
116 
117 version (REMOVE_SHORTCUT_ARROW)
118 extern (Windows)
119 nothrow @nogc
120 int WinMain(core.sys.windows.windef.HINSTANCE hInstance, core.sys.windows.windef.HINSTANCE hPrevInstance, core.sys.windows.winnt.LPSTR pCmdLine, int nCmdShow)
121 
122 	do
123 	{
124 		version (IS_WINREG) {
125 			return (.remove_windows_shortcut_arrow()) ? (0) : (1);
126 		} else {
127 			return (.reg_remove_windows_shortcut_arrow()) ? (0) : (1);
128 		}
129 	}