Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,18 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
include $(ROOT_REPLICANT)/PlatformName.mk
LOCAL_MODULE := ssdp
LOCAL_MODULE_FILENAME := lib$(LOCAL_MODULE).$(PLATFORM_NAME).w6c
LOCAL_C_INCLUDES := $(ROOT_REPLICANT)
LOCAL_CFLAGS := -fvisibility=hidden
LOCAL_STATIC_LIBRARIES := nu foundation
LOCAL_SHARED_LIBRARIES := libjnet nx
LOCAL_SRC_FILES := main.cpp SSDPAPI.cpp
LOCAL_LDFLAGS = -llog
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,436 @@
#include "api__ssdp.h"
#include "SSDPAPI.h"
#include "foundation/error.h"
#include "jnetlib/jnetlib.h"
#include "nx/nxsleep.h"
#include "nswasabi/AutoCharNX.h"
#include "nswasabi/ReferenceCounted.h"
#include <time.h>
#include <stdio.h>
#ifdef __ANDROID__
#include <android/log.h>
#endif
#ifdef _WIN32
#define snprintf _snprintf
#endif
SSDPAPI::SSDPAPI()
{
listener=0;
user_agent=0;
}
SSDPAPI::~SSDPAPI()
{
jnl_udp_release(listener);
for (ServiceList::iterator itr=services.begin();itr!=services.end();itr++)
{
NXURIRelease(itr->location);
NXStringRelease(itr->type);
NXStringRelease(itr->usn);
}
for (ServiceList::iterator itr=found_services.begin();itr!=found_services.end();itr++)
{
NXURIRelease(itr->location);
NXStringRelease(itr->type);
NXStringRelease(itr->usn);
}
}
int SSDPAPI::Initialize()
{
user_agent=WASABI2_API_APP->GetUserAgent();
NXThreadCreate(&ssdp_thread, SSDPThread, this);
return NErr_Success;
}
int SSDPAPI::SSDP_RegisterService(nx_uri_t location, nx_string_t type, nx_string_t usn)
{
nu::AutoLock auto_lock(services_lock);
Service service = {0};
service.location = NXURIRetain(location);
service.type = NXStringRetain(type);
service.usn = NXStringRetain(usn);
services.push_back(service);
return NErr_Success;
}
int SSDPAPI::SSDP_RegisterCallback(cb_ssdp *callback)
{
if (!callback)
{
return NErr_BadParameter;
}
threadloop_node_t *node = thread_loop.GetAPC();
if (!node)
{
return NErr_OutOfMemory;
}
node->func = APC_RegisterCallback;
node->param1 = this;
node->param2 = callback;
callback->Retain();
thread_loop.Schedule(node);
return NErr_Success;
}
int SSDPAPI::SSDP_UnregisterCallback(cb_ssdp *callback)
{
if (!callback)
{
return NErr_BadParameter;
}
threadloop_node_t *node = thread_loop.GetAPC();
if (!node)
{
return NErr_OutOfMemory;
}
node->func = APC_UnregisterCallback;
node->param1 = this;
node->param2 = callback;
// since we don't actually know if the callback is registered until the other thread runs
// we can't guarantee that we have a reference. so we'll add one!
callback->Retain();
thread_loop.Schedule(node);
return NErr_Success;
}
int SSDPAPI::SSDP_Search(nx_string_t type)
{
if (!type)
{
return NErr_BadParameter;
}
threadloop_node_t *node = thread_loop.GetAPC();
if (!node)
{
return NErr_OutOfMemory;
}
node->func = APC_Search;
node->param1 = this;
node->param2 = NXStringRetain(type);
thread_loop.Schedule(node);
return NErr_Success;
}
int SSDPAPI::FindUSN(ServiceList &service_list, const char *usn, Service *&service)
{
for (ServiceList::iterator itr = service_list.begin(); itr != service_list.end(); itr++)
{
if (!NXStringKeywordCompareWithCString(itr->usn, usn))
{
service = &(* itr);
return NErr_Success;
}
}
size_t num_services = service_list.size();
Service new_service = {0};
NXStringCreateWithUTF8(&new_service.usn, usn);
service_list.push_back(new_service);
service = &service_list.at(num_services);
return NErr_Empty;
}
nx_thread_return_t SSDPAPI::SSDPThread(nx_thread_parameter_t parameter)
{
return ((SSDPAPI *)parameter)->Internal_Run();
}
void SSDPAPI::Internal_RegisterCallback(cb_ssdp *callback)
{
callbacks.push_back(callback);
nu::AutoLock auto_lock(services_lock);
for (ServiceList::iterator itr=found_services.begin();itr!=found_services.end();itr++)
{
callback->OnServiceConnected(itr->location, itr->type, itr->usn);
}
}
void SSDPAPI::Internal_UnregisterCallback(cb_ssdp *callback)
{
// TODO: verify that our list actually contains the callback?
//callbacks.eraseObject(callback);
auto it = std::find(callbacks.begin(), callbacks.end(), callback);
if (it != callbacks.end())
{
callbacks.erase(it);
}
callback->Release(); // release the reference retained on the other thread
callback->Release(); // release _our_ reference
}
nx_thread_return_t SSDPAPI::Internal_Run()
{
addrinfo *addr = 0;
jnl_dns_resolve_now("239.255.255.250", 1900, &addr, SOCK_DGRAM);
int ret = jnl_udp_create_multicast_listener(&listener, "239.255.255.250", 1900);
if (ret != NErr_Success || !addr)
return (nx_thread_return_t)ret;
jnl_httpu_request_t httpu;
ret = jnl_httpu_request_create(&httpu);
if (ret != NErr_Success)
{
return (nx_thread_return_t)ret;
}
time_t last_notify = 0;
for (;;)
{
time_t now = time(0);
if ((now - last_notify) > 15)
{
Internal_Notify(0, addr->ai_addr, (socklen_t)addr->ai_addrlen);
if (ret != NErr_Success)
{
// TODO: ?
}
last_notify = time(0);
#if 0
#if defined(_DEBUG) && defined(_WIN32)
FILE *f = fopen("c:/services.txt", "wb");
if (f)
{
for (ServiceList::iterator itr=found_services.begin();itr!=found_services.end();itr++)
{
fprintf(f, "-----\r\n");
fprintf(f, "ST: %s\r\n", AutoCharPrintfUTF8(itr->type));
fprintf(f, "Location: %s\r\n", AutoCharPrintfUTF8(itr->location));
fprintf(f, "USN: %s\r\n", AutoCharPrintfUTF8(itr->usn));
}
fclose(f);
}
#elif defined(__ANDROID__)
for (ServiceList::iterator itr=found_services.begin();itr!=found_services.end();itr++)
{
__android_log_print(ANDROID_LOG_INFO, "libreplicant", "-----\r\n");
__android_log_print(ANDROID_LOG_INFO, "libreplicant", "ST: %s\r\n", AutoCharPrintfUTF8(itr->type));
__android_log_print(ANDROID_LOG_INFO, "libreplicant", "Location: %s\r\n", AutoCharPrintfUTF8(itr->location));
__android_log_print(ANDROID_LOG_INFO, "libreplicant", "USN: %s\r\n", AutoCharPrintfUTF8(itr->usn));
}
#endif
#endif
}
thread_loop.Step(100);
for (;;)
{
size_t bytes_received=0;
jnl_udp_run(listener, 0, 8192, 0, &bytes_received);
if (bytes_received)
{
jnl_httpu_request_process(httpu, listener);
const char *method = jnl_httpu_request_get_method(httpu);
if (method)
{
if (!strcmp(method, "NOTIFY"))
{
unsigned int max_age=0;
const char *cache_control = jnl_httpu_request_get_header(httpu, "cache-control");
if (cache_control)
{
if (strncasecmp(cache_control, "max-age=", 8) == 0)
{
max_age = strtoul(cache_control+8, 0, 10);
}
}
const char *location = jnl_httpu_request_get_header(httpu, "location");
const char *nt = jnl_httpu_request_get_header(httpu, "nt");
const char *nts = jnl_httpu_request_get_header(httpu, "nts");
const char *usn = jnl_httpu_request_get_header(httpu, "usn");
// a hack to work with older android wifi sync protocol
if (!usn)
usn = jnl_httpu_request_get_header(httpu, "id");
if (usn && nt && location && nts && !strcmp(nts, "ssdp:alive"))
{
Service *service = 0;
int ret = FindUSN(found_services, usn, service);
if (ret == NErr_Success) // found an existing one
{
// update the last seen time and expiration date
// TODO: should we double check that the location didn't change?
bool changed=false;
ReferenceCountedNXString old_location;
if (service->location)
NXURIGetNXString(&old_location, service->location);
if (!service->location || NXStringKeywordCompareWithCString(old_location, location))
{
NXURIRelease(service->location);
NXURICreateWithUTF8(&service->location, location);
changed=true;
}
service->last_seen = time(0);
if (max_age)
service->expiry = service->last_seen + max_age;
else
service->expiry = (time_t)-1;
if (changed)
{
// notify clients
for (CallbackList::iterator itr=callbacks.begin();itr!=callbacks.end();itr++)
{
(*itr)->OnServiceDisconnected(service->usn);
(*itr)->OnServiceConnected(service->location, service->type, service->usn);
}
}
}
else if (ret == NErr_Empty) // new one
{
NXURICreateWithUTF8(&service->location, location);
NXStringCreateWithUTF8(&service->type, nt);
service->last_seen = time(0);
if (max_age)
service->expiry = service->last_seen + max_age;
else
service->expiry = (time_t)-1;
// notify clients
for (CallbackList::iterator itr=callbacks.begin();itr!=callbacks.end();itr++)
{
(*itr)->OnServiceConnected(service->location, service->type, service->usn);
}
}
}
}
else if (!strcmp(method, "M-SEARCH"))
{
sockaddr *addr; socklen_t addr_length;
jnl_udp_get_address(listener, &addr, &addr_length);
const char *st = jnl_httpu_request_get_header(httpu, "st");
Internal_Notify(st, addr, addr_length);
}
}
}
else
{
break;
}
}
// check for expirations
again:
nu::AutoLock auto_lock(services_lock);
for (ServiceList::iterator itr=found_services.begin();itr!=found_services.end();itr++)
{
if (itr->expiry < now)
{
for (CallbackList::iterator itr2=callbacks.begin();itr2!=callbacks.end();itr2++)
{
(*itr2)->OnServiceDisconnected(itr->usn);
}
NXURIRelease(itr->location);
NXStringRelease(itr->usn);
NXStringRelease(itr->type);
found_services.erase(itr);
goto again;
}
}
}
return 0;
}
static char notify_request[] = "NOTIFY * HTTP/1.1\r\n";
static char notify_host[] = "HOST: 239.255.255.250:1900\r\n";
static char notify_cache_control[] = "CACHE-CONTROL:max-age=600\r\n";
static char notify_nts[] = "NTS:ssdp:alive\r\n";
static char search_request[] = "NOTIFY * HTTP/1.1\r\n";
static char search_man[] = "MAN:\"ssdp:discover\"\r\n";
ns_error_t SSDPAPI::Internal_Notify(const char *st, sockaddr *addr, socklen_t addr_length)
{
jnl_udp_set_peer_address(listener, addr, addr_length);
nu::AutoLock auto_lock(services_lock);
for (ServiceList::iterator itr=services.begin();itr!=services.end();itr++)
{
if (st && NXStringKeywordCompareWithCString(itr->type, st))
continue;
jnl_udp_send(listener, notify_request, strlen(notify_request));
jnl_udp_send(listener, notify_host, strlen(notify_host));
jnl_udp_send(listener, notify_cache_control, strlen(notify_cache_control));
jnl_udp_send(listener, notify_nts, strlen(notify_nts));
char header[512] = {0};
snprintf(header, 511, "LOCATION:%s\r\n", AutoCharPrintfUTF8(itr->location));
header[511]=0;
jnl_udp_send(listener, header, strlen(header));
if (itr->usn)
{
snprintf(header, 511, "USN:%s\r\n", AutoCharPrintfUTF8(itr->usn));
header[511]=0;
jnl_udp_send(listener, header, strlen(header));
}
if (itr->type)
{
snprintf(header, 511, "NT:%s\r\n", AutoCharPrintfUTF8(itr->type));
header[511]=0;
jnl_udp_send(listener, header, strlen(header));
}
if (user_agent)
{
snprintf(header, 511, "SERVER:%s\r\n",user_agent);
header[511]=0;
jnl_udp_send(listener, header, strlen(header));
}
jnl_udp_send(listener, "\r\n", 2);
size_t bytes_sent=0;
do
{
jnl_udp_run(listener, 8192, 0, &bytes_sent, 0); // TODO: error check
if (bytes_sent == 0)
NXSleep(100);
} while (bytes_sent == 0);
}
return NErr_Success;
}
void SSDPAPI::Internal_Search(nx_string_t st)
{
addrinfo *addr;
jnl_dns_resolve_now("239.255.255.250", 1900, &addr, SOCK_DGRAM);
jnl_udp_set_peer_address(listener, addr->ai_addr, (socklen_t)addr->ai_addrlen);
jnl_udp_send(listener, notify_request, strlen(notify_request));
jnl_udp_send(listener, search_request, strlen(search_request));
jnl_udp_send(listener, notify_host, strlen(notify_host));
jnl_udp_send(listener, search_man, strlen(search_man));
char header[512] = {0};
sprintf(header, "ST:%s\r\n", AutoCharPrintfUTF8(st));
header[511]=0;
jnl_udp_send(listener, header, strlen(header));
size_t bytes_sent=0;
do
{
jnl_udp_run(listener, 8192, 0, &bytes_sent, 0); // TODO: error check
if (bytes_sent == 0)
NXSleep(100);
} while (bytes_sent == 0);
}

View file

@ -0,0 +1,61 @@
#pragma once
#include "nx/nxstring.h"
#include "nx/nxuri.h"
#include <vector>
#include "nu/AutoLock.h"
#include "nx/nxthread.h"
#include "foundation/error.h"
#include "jnetlib/jnetlib.h"
#include "cb_ssdp.h"
#include "nu/ThreadLoop.h"
#include "api_ssdp.h"
#include "nswasabi/ServiceName.h"
class SSDPAPI : public api_ssdp
{
public:
SSDPAPI();
~SSDPAPI();
WASABI_SERVICE_NAME("SSDP API");
int Initialize();
int WASABICALL SSDP_RegisterService(nx_uri_t location, nx_string_t st, nx_string_t usn);
int WASABICALL SSDP_RegisterCallback(cb_ssdp *callback);
int WASABICALL SSDP_UnregisterCallback(cb_ssdp *callback);
int WASABICALL SSDP_Search(nx_string_t st);
private:
struct Service
{
nx_uri_t location;
nx_string_t type;
nx_string_t usn;
time_t last_seen;
time_t expiry;
};
// TODO: map it off of USN
typedef std::vector<Service> ServiceList;
typedef std::vector<cb_ssdp*> CallbackList;
nx_thread_return_t Internal_Run();
ns_error_t Internal_Notify(const char *st, sockaddr *addr, socklen_t length);
void Internal_RegisterCallback(cb_ssdp *callback);
void Internal_UnregisterCallback(cb_ssdp *callback);
void Internal_Search(nx_string_t st);
static nx_thread_return_t NXTHREADCALL SSDPThread(nx_thread_parameter_t parameter);
int FindUSN(ServiceList &service_list, const char *usn, Service *&service);
ThreadLoop thread_loop;
CallbackList callbacks;
ServiceList services;
ServiceList found_services;
nu::LockGuard services_lock;
nx_thread_t ssdp_thread;
jnl_udp_t listener;
const char *user_agent;
static void APC_RegisterCallback(void *_this, void *_callback, double) { ((SSDPAPI *)_this)->Internal_RegisterCallback((cb_ssdp *)_callback); }
static void APC_UnregisterCallback(void *_this, void *_callback, double) { ((SSDPAPI *)_this)->Internal_UnregisterCallback((cb_ssdp *)_callback); }
static void APC_Search(void *_this, void *st, double) { ((SSDPAPI *)_this)->Internal_Search((nx_string_t)st); }
};

View file

@ -0,0 +1,20 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <foundation/types.h>
#include "service/api_service.h"
extern api_service *serviceManager;
#define WASABI2_API_SVC serviceManager
#include "application/api_application.h"
extern api_application *applicationApi;
#define WASABI2_API_APP applicationApi
#include "syscb/api_syscb.h"
extern api_syscb *syscbApi;
#define WASABI2_API_SYSCB syscbApi
//#include "application/api_android.h"
//extern api_android *androidApi;
//#define WASABI2_API_ANDROID androidApi

View file

@ -0,0 +1,32 @@
#pragma once
#include "service/types.h"
#include "nx/nxuri.h"
#include "nx/nxstring.h"
#include "cb_ssdp.h"
// {A2EF43B6-5044-4D44-AE38-71C2CE20587B}
static const GUID ssdp_api_service_guid =
{ 0xa2ef43b6, 0x5044, 0x4d44, { 0xae, 0x38, 0x71, 0xc2, 0xce, 0x20, 0x58, 0x7b } };
class api_ssdp : public Wasabi2::Dispatchable
{
protected:
api_ssdp() : Wasabi2::Dispatchable(DISPATCHABLE_VERSION) {}
~api_ssdp() {}
public:
static GUID GetServiceType() { return SVC_TYPE_UNIQUE; }
static GUID GetServiceGUID() { return ssdp_api_service_guid; }
int RegisterService(nx_uri_t location, nx_string_t st, nx_string_t usn) { return SSDP_RegisterService(location, st, usn); }
int RegisterCallback(cb_ssdp *callback) { return SSDP_RegisterCallback(callback); }
int UnregisterCallback(cb_ssdp *callback) { return SSDP_UnregisterCallback(callback); }
int Search(nx_string_t st) { return SSDP_Search(st); }
private:
virtual int WASABICALL SSDP_RegisterService(nx_uri_t location, nx_string_t st, nx_string_t usn)=0;
virtual int WASABICALL SSDP_RegisterCallback(cb_ssdp *callback)=0;
virtual int WASABICALL SSDP_UnregisterCallback(cb_ssdp *callback)=0;
virtual int WASABICALL SSDP_Search(nx_string_t st)=0;
enum
{
DISPATCHABLE_VERSION=0,
};
};

View file

@ -0,0 +1,21 @@
#pragma once
#include "foundation/dispatch.h"
class cb_ssdp : public Wasabi2::Dispatchable
{
protected:
cb_ssdp() : Wasabi2::Dispatchable(DISPATCHABLE_VERSION) {}
~cb_ssdp() {}
public:
void OnServiceConnected(nx_uri_t location, nx_string_t type, nx_string_t usn) { return SSDPCallback_OnServiceConnected(location, type, usn); }
void OnServiceDisconnected(nx_string_t usn) { return SSDPCallback_OnServiceDisconnected(usn); }
enum
{
DISPATCHABLE_VERSION=0,
};
private:
virtual void WASABICALL SSDPCallback_OnServiceConnected(nx_uri_t location, nx_string_t type, nx_string_t usn)=0;
virtual void WASABICALL SSDPCallback_OnServiceDisconnected(nx_string_t usn)=0;
};

View file

@ -0,0 +1,88 @@
#include "api__ssdp.h"
#include "foundation/export.h"
#include "component/ifc_component.h"
#include "nx/nxuri.h"
#include "nswasabi/ReferenceCounted.h"
#include "nswasabi/singleton.h"
#include "SSDPAPI.h"
api_service *WASABI2_API_SVC=0;
api_application *WASABI2_API_APP=0;
api_syscb *WASABI2_API_SYSCB=0;
//api_android *WASABI2_API_ANDROID=0;
SSDPAPI ssdpapi;
static SingletonServiceFactory<SSDPAPI, api_ssdp> ssdp_factory;
// {F47F99AB-F90F-4623-B8BE-454555A8FC79}
static const GUID ssdp_component_guid =
{ 0xf47f99ab, 0xf90f, 0x4623, { 0xb8, 0xbe, 0x45, 0x45, 0x55, 0xa8, 0xfc, 0x79 } };
class SSDPComponent : public ifc_component
{
public:
SSDPComponent() : ifc_component(ssdp_component_guid) {}
int WASABICALL Component_Initialize(api_service *service);
int WASABICALL Component_RegisterServices(api_service *service);
void WASABICALL Component_DeregisterServices(api_service *service);
int WASABICALL Component_Quit(api_service *service);
};
int SSDPComponent::Component_Initialize(api_service *service)
{
WASABI2_API_SVC = service;
int ret = jnl_init();
if (ret != NErr_Success)
{
return ret;
}
return NErr_Success;
}
int SSDPComponent::Component_RegisterServices(api_service *service)
{
WASABI2_API_SVC = service;
if (WASABI2_API_SVC)
{
WASABI2_API_SVC->GetService(&WASABI2_API_APP);
WASABI2_API_SVC->GetService(&WASABI2_API_SYSCB);
//WASABI2_API_SVC->GetService(&WASABI2_API_ANDROID);
}
ssdpapi.Initialize();
ssdp_factory.Register(WASABI2_API_SVC, &ssdpapi);
return NErr_Success;
}
void SSDPComponent::Component_DeregisterServices(api_service *service)
{
if (WASABI2_API_SVC)
WASABI2_API_SVC->Release();
if (WASABI2_API_APP)
WASABI2_API_APP->Release();
if (WASABI2_API_SYSCB)
WASABI2_API_SYSCB->Release();
//if (WASABI2_API_ANDROID)
// WASABI2_API_ANDROID->Release();
ssdp_factory.Deregister(WASABI2_API_SVC);
}
int SSDPComponent::Component_Quit(api_service *_service_manager)
{
jnl_quit();
return NErr_Success;
}
static SSDPComponent component;
extern "C" DLLEXPORT ifc_component *GetWasabi2Component()
{
return &component;
}

View file

@ -0,0 +1 @@
#pragma once

View file

@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ssdp.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -0,0 +1,76 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,302 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{05DA3583-A0EC-4BD3-AF29-9703289F033C}</ProjectGuid>
<RootNamespace>ssdp</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.32203.90</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<TargetExt>.w6c</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<TargetExt>.w6c</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetExt>.w6c</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetExt>.w6c</TargetExt>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;_DEBUG;_WINDOWS;_USRDLL;SSDP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(IntDir)$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;_WINDOWS;_USRDLL;SSDP_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;SSDP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(IntDir)$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MinSpace</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;SSDP_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Components\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\jnetlib\jnetlib.vcxproj">
<Project>{e105a0a2-7391-47c5-86ac-718003524c3d}</Project>
</ProjectReference>
<ProjectReference Include="..\nu\nu.vcxproj">
<Project>{f1f5cd60-0d5b-4cea-9eeb-2f87ff9aa915}</Project>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\nx\nx.vcxproj">
<Project>{57c90706-b25d-4aca-9b33-95cdb2427c27}</Project>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="SSDPAPI.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__ssdp.h" />
<ClInclude Include="api_ssdp.h" />
<ClInclude Include="cb_ssdp.h" />
<ClInclude Include="main.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SSDPAPI.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ssdp.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{82598013-881a-4b89-82bf-dc514bcc744a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SSDPAPI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__ssdp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api_ssdp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cb_ssdp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SSDPAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ssdp.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View file

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION WINAMP_PRODUCTVER
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp 5.x Replicant Component"
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
VALUE "InternalName", "ssdp.w6c"
VALUE "LegalCopyright", "Copyright © 2012-2014 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "ssdp.w6c"
VALUE "ProductName", "Winamp SSDP API Service"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END