| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
#ifdef HAVE_CONFIG_H |
|---|
| 26 |
# include "config.h" |
|---|
| 27 |
#endif |
|---|
| 28 |
|
|---|
| 29 |
#define UNICODE |
|---|
| 30 |
#include <vlc_common.h> |
|---|
| 31 |
#include "../libvlc.h" |
|---|
| 32 |
#include <vlc_playlist.h> |
|---|
| 33 |
#include <vlc_charset.h> |
|---|
| 34 |
|
|---|
| 35 |
#include "../extras/getopt.h" |
|---|
| 36 |
|
|---|
| 37 |
#if !defined( UNDER_CE ) |
|---|
| 38 |
# include <io.h> |
|---|
| 39 |
# include <fcntl.h> |
|---|
| 40 |
# include <mmsystem.h> |
|---|
| 41 |
#endif |
|---|
| 42 |
|
|---|
| 43 |
#include <winsock.h> |
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
void system_Init( libvlc_int_t *p_this, int *pi_argc, const char *ppsz_argv[] ) |
|---|
| 49 |
{ |
|---|
| 50 |
WSADATA Data; |
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
char psz_path[MAX_PATH]; |
|---|
| 54 |
char *psz_vlc; |
|---|
| 55 |
|
|---|
| 56 |
wchar_t psz_wpath[MAX_PATH]; |
|---|
| 57 |
if( GetModuleFileName( NULL, psz_wpath, MAX_PATH ) ) |
|---|
| 58 |
{ |
|---|
| 59 |
WideCharToMultiByte( CP_ACP, 0, psz_wpath, -1, |
|---|
| 60 |
psz_path, MAX_PATH, NULL, NULL ); |
|---|
| 61 |
} |
|---|
| 62 |
else psz_path[0] = '\0'; |
|---|
| 63 |
|
|---|
| 64 |
if( (psz_vlc = strrchr( psz_path, '\\' )) ) *psz_vlc = '\0'; |
|---|
| 65 |
|
|---|
| 66 |
#ifndef HAVE_RELEASE |
|---|
| 67 |
{ |
|---|
| 68 |
|
|---|
| 69 |
|
|---|
| 70 |
int offset = strlen(psz_path)-sizeof("\\.libs")+1; |
|---|
| 71 |
if( offset > 0 ) |
|---|
| 72 |
{ |
|---|
| 73 |
psz_vlc = psz_path+offset; |
|---|
| 74 |
if( ! strcmp(psz_vlc, "\\.libs") ) *psz_vlc = '\0'; |
|---|
| 75 |
} |
|---|
| 76 |
} |
|---|
| 77 |
#endif |
|---|
| 78 |
|
|---|
| 79 |
vlc_global()->psz_vlcpath = strdup( psz_path ); |
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
#if !defined( UNDER_CE ) |
|---|
| 83 |
_fmode = _O_BINARY; |
|---|
| 84 |
_setmode( _fileno( stdin ), _O_BINARY ); |
|---|
| 85 |
|
|---|
| 86 |
timeBeginPeriod(5); |
|---|
| 87 |
#endif |
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
mdate(); |
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
if( !WSAStartup( MAKEWORD( 2, 2 ), &Data ) ) |
|---|
| 94 |
{ |
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 |
if( LOBYTE( Data.wVersion ) != 2 || HIBYTE( Data.wVersion ) != 2 ) |
|---|
| 98 |
|
|---|
| 99 |
WSACleanup( ); |
|---|
| 100 |
else |
|---|
| 101 |
|
|---|
| 102 |
return; |
|---|
| 103 |
} |
|---|
| 104 |
|
|---|
| 105 |
|
|---|
| 106 |
if( !WSAStartup( MAKEWORD( 1, 1 ), &Data ) ) |
|---|
| 107 |
{ |
|---|
| 108 |
|
|---|
| 109 |
if( LOBYTE( Data.wVersion ) != 1 || HIBYTE( Data.wVersion ) != 1 ) |
|---|
| 110 |
|
|---|
| 111 |
WSACleanup( ); |
|---|
| 112 |
else |
|---|
| 113 |
|
|---|
| 114 |
return; |
|---|
| 115 |
} |
|---|
| 116 |
|
|---|
| 117 |
fprintf( stderr, "error: can't initialize WinSocks\n" ); |
|---|
| 118 |
} |
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
static unsigned __stdcall IPCHelperThread( void * ); |
|---|
| 124 |
LRESULT CALLBACK WMCOPYWNDPROC( HWND, UINT, WPARAM, LPARAM ); |
|---|
| 125 |
static vlc_object_t *p_helper = NULL; |
|---|
| 126 |
static unsigned long hIPCHelper; |
|---|
| 127 |
|
|---|
| 128 |
typedef struct |
|---|
| 129 |
{ |
|---|
| 130 |
int argc; |
|---|
| 131 |
int enqueue; |
|---|
| 132 |
char data[0]; |
|---|
| 133 |
} vlc_ipc_data_t; |
|---|
| 134 |
|
|---|
| 135 |
void system_Configure( libvlc_int_t *p_this, int *pi_argc, const char *ppsz_argv[] ) |
|---|
| 136 |
{ |
|---|
| 137 |
#if !defined( UNDER_CE ) |
|---|
| 138 |
|
|---|
| 139 |
#ifndef ABOVE_NORMAL_PRIORITY_CLASS |
|---|
| 140 |
# define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 |
|---|
| 141 |
#endif |
|---|
| 142 |
if( config_GetInt( p_this, "high-priority" ) ) |
|---|
| 143 |
{ |
|---|
| 144 |
if( SetPriorityClass( GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS ) |
|---|
| 145 |
|| SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) |
|---|
| 146 |
{ |
|---|
| 147 |
msg_Dbg( p_this, "raised process priority" ); |
|---|
| 148 |
} |
|---|
| 149 |
else |
|---|
| 150 |
{ |
|---|
| 151 |
msg_Dbg( p_this, "could not raise process priority" ); |
|---|
| 152 |
} |
|---|
| 153 |
} |
|---|
| 154 |
|
|---|
| 155 |
if( config_GetInt( p_this, "one-instance" ) |
|---|
| 156 |
|| ( config_GetInt( p_this, "one-instance-when-started-from-file" ) |
|---|
| 157 |
&& config_GetInt( p_this, "started-from-file" ) ) ) |
|---|
| 158 |
{ |
|---|
| 159 |
HANDLE hmutex; |
|---|
| 160 |
|
|---|
| 161 |
msg_Info( p_this, "one instance mode ENABLED"); |
|---|
| 162 |
|
|---|
| 163 |
|
|---|
| 164 |
if( !( hmutex = CreateMutex( 0, TRUE, L"VLC ipc "VERSION ) ) ) |
|---|
| 165 |
{ |
|---|
| 166 |
|
|---|
| 167 |
|
|---|
| 168 |
msg_Err( p_this, "one instance mode DISABLED " |
|---|
| 169 |
"(mutex couldn't be created)" ); |
|---|
| 170 |
return; |
|---|
| 171 |
} |
|---|
| 172 |
|
|---|
| 173 |
if( GetLastError() != ERROR_ALREADY_EXISTS ) |
|---|
| 174 |
{ |
|---|
| 175 |
|
|---|
| 176 |
static const char typename[] = "ipc helper"; |
|---|
| 177 |
p_helper = |
|---|
| 178 |
vlc_custom_create( p_this, sizeof(vlc_object_t), |
|---|
| 179 |
VLC_OBJECT_GENERIC, typename ); |
|---|
| 180 |
vlc_object_lock( p_helper ); |
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 |
hIPCHelper = _beginthreadex( NULL, 0, IPCHelperThread, p_helper, |
|---|
| 184 |
0, NULL ); |
|---|
| 185 |
if( hIPCHelper ) |
|---|
| 186 |
vlc_object_wait( p_helper ); |
|---|
| 187 |
vlc_object_unlock( p_helper ); |
|---|
| 188 |
|
|---|
| 189 |
if( !hIPCHelper ) |
|---|
| 190 |
{ |
|---|
| 191 |
msg_Err( p_this, "one instance mode DISABLED " |
|---|
| 192 |
"(IPC helper thread couldn't be created)" ); |
|---|
| 193 |
vlc_object_release (p_helper); |
|---|
| 194 |
p_helper = NULL; |
|---|
| 195 |
} |
|---|
| 196 |
vlc_object_attach (p_helper, p_this); |
|---|
| 197 |
|
|---|
| 198 |
|
|---|
| 199 |
|
|---|
| 200 |
ReleaseMutex( hmutex ); |
|---|
| 201 |
} |
|---|
| 202 |
else |
|---|
| 203 |
{ |
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
HWND ipcwindow; |
|---|
| 207 |
|
|---|
| 208 |
|
|---|
| 209 |
WaitForSingleObject( hmutex, INFINITE ); |
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 |
if( !( ipcwindow = FindWindow( 0, L"VLC ipc "VERSION ) ) ) |
|---|
| 214 |
{ |
|---|
| 215 |
msg_Err( p_this, "one instance mode DISABLED " |
|---|
| 216 |
"(couldn't find 1st instance of program)" ); |
|---|
| 217 |
ReleaseMutex( hmutex ); |
|---|
| 218 |
return; |
|---|
| 219 |
} |
|---|
| 220 |
|
|---|
| 221 |
|
|---|
| 222 |
|
|---|
| 223 |
if( *pi_argc - 1 >= optind ) |
|---|
| 224 |
{ |
|---|
| 225 |
COPYDATASTRUCT wm_data; |
|---|
| 226 |
int i_opt; |
|---|
| 227 |
vlc_ipc_data_t *p_data; |
|---|
| 228 |
size_t i_data = sizeof (*p_data); |
|---|
| 229 |
|
|---|
| 230 |
for( i_opt = optind; i_opt < *pi_argc; i_opt++ ) |
|---|
| 231 |
{ |
|---|
| 232 |
i_data += sizeof (size_t); |
|---|
| 233 |
i_data += strlen( ppsz_argv[ i_opt ] ) + 1; |
|---|
| 234 |
} |
|---|
| 235 |
|
|---|
| 236 |
p_data = malloc( i_data ); |
|---|
| 237 |
p_data->argc = *pi_argc - optind; |
|---|
| 238 |
p_data->enqueue = config_GetInt( p_this, "playlist-enqueue" ); |
|---|
| 239 |
i_data = 0; |
|---|
| 240 |
for( i_opt = optind; i_opt < *pi_argc; i_opt++ ) |
|---|
| 241 |
{ |
|---|
| 242 |
size_t i_len = strlen( ppsz_argv[ i_opt ] ) + 1; |
|---|
| 243 |
|
|---|
| 244 |
|
|---|
| 245 |
*((size_t *)(p_data->data + i_data)) = i_len; |
|---|
| 246 |
i_data += sizeof (size_t); |
|---|
| 247 |
memcpy( &p_data->data[i_data], ppsz_argv[ i_opt ], i_len ); |
|---|
| 248 |
i_data += i_len; |
|---|
| 249 |
} |
|---|
| 250 |
i_data += sizeof (*p_data); |
|---|
| 251 |
|
|---|
| 252 |
|
|---|
| 253 |
wm_data.dwData = 0; |
|---|
| 254 |
wm_data.cbData = i_data; |
|---|
| 255 |
wm_data.lpData = p_data; |
|---|
| 256 |
SendMessage( ipcwindow, WM_COPYDATA, 0, (LPARAM)&wm_data ); |
|---|
| 257 |
} |
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
|
|---|
| 261 |
ReleaseMutex( hmutex ); |
|---|
| 262 |
|
|---|
| 263 |
|
|---|
| 264 |
system_End( p_this ); |
|---|
| 265 |
exit( 0 ); |
|---|
| 266 |
} |
|---|
| 267 |
} |
|---|
| 268 |
|
|---|
| 269 |
#endif |
|---|
| 270 |
} |
|---|
| 271 |
|
|---|
| 272 |
static unsigned __stdcall IPCHelperThread( void *data ) |
|---|
| 273 |
{ |
|---|
| 274 |
vlc_object_t *p_this = data; |
|---|
| 275 |
HWND ipcwindow; |
|---|
| 276 |
MSG message; |
|---|
| 277 |
|
|---|
| 278 |
ipcwindow = |
|---|
| 279 |
CreateWindow( L"STATIC", |
|---|
| 280 |
L"VLC ipc "VERSION, |
|---|
| 281 |
0, |
|---|
| 282 |
0, |
|---|
| 283 |
0, |
|---|
| 284 |
0, |
|---|
| 285 |
0, |
|---|
| 286 |
NULL, |
|---|
| 287 |
NULL, |
|---|
| 288 |
GetModuleHandle(NULL), |
|---|
| 289 |
NULL ); |
|---|
| 290 |
|
|---|
| 291 |
SetWindowLongPtr( ipcwindow, GWLP_WNDPROC, (LRESULT)WMCOPYWNDPROC ); |
|---|
| 292 |
SetWindowLongPtr( ipcwindow, GWLP_USERDATA, (LONG_PTR)p_this ); |
|---|
| 293 |
|
|---|
| 294 |
|
|---|
| 295 |
vlc_object_signal( p_this ); |
|---|
| 296 |
|
|---|
| 297 |
while( GetMessage( &message, NULL, 0, 0 ) ) |
|---|
| 298 |
{ |
|---|
| 299 |
TranslateMessage( &message ); |
|---|
| 300 |
DispatchMessage( &message ); |
|---|
| 301 |
} |
|---|
| 302 |
return 0; |
|---|
| 303 |
} |
|---|
| 304 |
|
|---|
| 305 |
LRESULT CALLBACK WMCOPYWNDPROC( HWND hwnd, UINT uMsg, WPARAM wParam, |
|---|
| 306 |
LPARAM lParam ) |
|---|
| 307 |
{ |
|---|
| 308 |
if( uMsg == WM_COPYDATA ) |
|---|
| 309 |
{ |
|---|
| 310 |
COPYDATASTRUCT *pwm_data = (COPYDATASTRUCT*)lParam; |
|---|
| 311 |
vlc_object_t *p_this; |
|---|
| 312 |
playlist_t *p_playlist; |
|---|
| 313 |
|
|---|
| 314 |
p_this = (vlc_object_t *) |
|---|
| 315 |
(uintptr_t)GetWindowLongPtr( hwnd, GWLP_USERDATA ); |
|---|
| 316 |
|
|---|
| 317 |
if( !p_this ) return 0; |
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 |
p_playlist = pl_Yield( p_this ); |
|---|
| 321 |
if( !p_playlist ) return 0; |
|---|
| 322 |
|
|---|
| 323 |
if( pwm_data->lpData ) |
|---|
| 324 |
{ |
|---|
| 325 |
char **ppsz_argv; |
|---|
| 326 |
vlc_ipc_data_t *p_data = (vlc_ipc_data_t *)pwm_data->lpData; |
|---|
| 327 |
size_t i_data = 0; |
|---|
| 328 |
int i_argc = p_data->argc, i_opt, i_options; |
|---|
| 329 |
|
|---|
| 330 |
ppsz_argv = (char **)malloc( i_argc * sizeof(char *) ); |
|---|
| 331 |
for( i_opt = 0; i_opt < i_argc; i_opt++ ) |
|---|
| 332 |
{ |
|---|
| 333 |
ppsz_argv[i_opt] = p_data->data + i_data + sizeof(int); |
|---|
| 334 |
i_data += sizeof(int) + *((int *)(p_data->data + i_data)); |
|---|
| 335 |
} |
|---|
| 336 |
|
|---|
| 337 |
for( i_opt = 0; i_opt < i_argc; i_opt++ ) |
|---|
| 338 |
{ |
|---|
| 339 |
i_options = 0; |
|---|
| 340 |
|
|---|
| 341 |
|
|---|
| 342 |
while( i_opt + i_options + 1 < i_argc && |
|---|
| 343 |
*ppsz_argv[ i_opt + i_options + 1 ] == ':' ) |
|---|
| 344 |
{ |
|---|
| 345 |
i_options++; |
|---|
| 346 |
} |
|---|
| 347 |
playlist_AddExt( p_playlist, ppsz_argv[i_opt], |
|---|
| 348 |
NULL, PLAYLIST_APPEND | |
|---|
| 349 |
( ( i_opt || p_data->enqueue ) ? 0 : PLAYLIST_GO ), |
|---|
| 350 |
PLAYLIST_END, -1, |
|---|
| 351 |
(char const **)( i_options ? &ppsz_argv[i_opt+1] : NULL ), |
|---|
| 352 |
i_options, true, pl_Unlocked ); |
|---|
| 353 |
|
|---|
| 354 |
i_opt += i_options; |
|---|
| 355 |
} |
|---|
| 356 |
|
|---|
| 357 |
free( ppsz_argv ); |
|---|
| 358 |
} |
|---|
| 359 |
|
|---|
| 360 |
vlc_object_release( p_playlist ); |
|---|
| 361 |
} |
|---|
| 362 |
|
|---|
| 363 |
return DefWindowProc( hwnd, uMsg, wParam, lParam ); |
|---|
| 364 |
} |
|---|
| 365 |
|
|---|
| 366 |
|
|---|
| 367 |
|
|---|
| 368 |
|
|---|
| 369 |
void system_End( libvlc_int_t *p_this ) |
|---|
| 370 |
{ |
|---|
| 371 |
if( p_this && vlc_global() ) |
|---|
| 372 |
{ |
|---|
| 373 |
free( vlc_global()->psz_vlcpath ); |
|---|
| 374 |
vlc_global()->psz_vlcpath = NULL; |
|---|
| 375 |
} |
|---|
| 376 |
if (p_helper && p_helper->p_parent == VLC_OBJECT(p_this) ) |
|---|
| 377 |
{ |
|---|
| 378 |
|
|---|
| 379 |
SendMessage( NULL, WM_QUIT, 0, 0 ); |
|---|
| 380 |
vlc_thread_join (p_helper); |
|---|
| 381 |
vlc_object_detach (p_helper); |
|---|
| 382 |
vlc_object_release (p_helper); |
|---|
| 383 |
p_helper = NULL; |
|---|
| 384 |
} |
|---|
| 385 |
|
|---|
| 386 |
#if !defined( UNDER_CE ) |
|---|
| 387 |
timeEndPeriod(5); |
|---|
| 388 |
#endif |
|---|
| 389 |
|
|---|
| 390 |
WSACleanup(); |
|---|
| 391 |
} |
|---|