Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - BlackZeroX

#21
Scripting.FileSystemObject... de hecho dicho objeto no parte de vb6 parte de vba, al final del día ya tiene varias formas de hacerlo

API Win32
Objetos COM (vba) en vb .NET

En cualquier caso según veo se debe ejecutar con privilegios de administrador, así que deberá agregar un MANIFEST para que escale permisos o que se ejecute con dicho permiso.

El código posteado por serapis (Solo parte del COM) por lo que se ve lista volúmenes lógicos y no físicos que para lo que se requiere es similar a este (VBS) crear un archivo en escritorio y con extensión "vbs" como ejecutar.vbs y pegar este código y darle doble click:

Código (vbs) [Seleccionar]

Dim fs, d, dc, s
Set fs = CreateObject("Scripting.FileSystemObject")
Set dc = fs.Drives
For Each d in dc
   s = s & d.DriveLetter & " tipo "  & d.DriveType & " serialNumber (Logico) "  & d.SerialNumber & vbNewLine
Next
MsgBox s


Saludos.
#22
Puedes omitir el llamado de ZeroMemory* en VB .NET las variables ya se inicializan limpias* y no se ve que las uses entre la declaracion y la implementación de las mismas.

ZeroMemory
La función ZeroMemory llena un bloque de memoria con ceros.

Sintaxis
VOID ZeroMemory (
    PVOID Destination,  // puntero al bloque a llenar con ceros
    DWORD Length,       // tamaño, en bytes, del bloque a llenar
   );
Parámetros
Destination: puntero a la dirección de comienzo del bloque de memoria a llenar con ceros.

Length: especifica el tamaño, en bytes, del bloque de memoria a llenar con ceros.

Valor de retorno
Esta función no tiene valor de retorno.

Saludos.
#23
Cita de: bybaal en  3 Febrero 2021, 04:46 AM
Alguien me pudiera aclarar como se puede obtener el número de serie de un disco físico, también el modelo del disco.

OJO!!! Que sea usando la API de Windows y en VB

GetVolumeInformationA function (fileapi.h)

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa

Encontré el uso en C/C++ solo tradúcelo y adáptalo a tus necesidades que tampoco creo en los foros se hagan encargos de codigo a modo.

https://gist.github.com/micjabbour/a2fbe50160862e6abe439c0b0769c3fb

Lo modifique para listara los números de serie de todos los discos físicos instalados (es un asco como lo adapte, lo se jajajaja).
Código (cpp) [Seleccionar]

#include <windows.h>
#include <memory>
#include <string>
#include <iostream>
#include <bitset>
#include <vector>

using namespace std;

#define CTL_CODE(DeviceType, Function, Method, Access) \
   (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define METHOD_BUFFERED 0

//returns the serial number of the first physical drive in a string or an empty string in case of failure
//based on http://codexpert.ro/blog/2013/10/26/get-physical-drive-serial-number-part-1/
string getFirstHddSerialNumber(wchar_t *pDisk) {
   //get a handle to the first physical drive
   HANDLE h = CreateFileW(pDisk, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
   if(h == INVALID_HANDLE_VALUE) return {};
   //an unique_ptr is used to perform cleanup automatically when returning (i.e. to avoid code duplication)
   unique_ptr<remove_pointer<HANDLE>::type, void(*)(HANDLE)> hDevice{h, [](HANDLE handle){CloseHandle(handle);}};
   //initialize a STORAGE_PROPERTY_QUERY data structure (to be used as input to DeviceIoControl)
   STORAGE_PROPERTY_QUERY storagePropertyQuery{};
   storagePropertyQuery.PropertyId= StorageDeviceProperty;
   storagePropertyQuery.QueryType= PropertyStandardQuery;
   //initialize a STORAGE_DESCRIPTOR_HEADER data structure (to be used as output from DeviceIoControl)
   STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader{};
   //the next call to DeviceIoControl retrieves necessary size (in order to allocate a suitable buffer)
   //call DeviceIoControl and return an empty string on failure
   DWORD dwBytesReturned= 0;
   if(!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
                       &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &dwBytesReturned, NULL))
       return {};
   //allocate a suitable buffer
   const DWORD dwOutBufferSize= storageDescriptorHeader.Size;
   unique_ptr<BYTE[]> pOutBuffer{new BYTE[dwOutBufferSize]{}};
   //call DeviceIoControl with the allocated buffer
   if(!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
                       pOutBuffer.get(), dwOutBufferSize, &dwBytesReturned, NULL))
       return {};
   //read and return the serial number out of the output buffer
   STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor= reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(pOutBuffer.get());
   const DWORD dwSerialNumberOffset= pDeviceDescriptor->SerialNumberOffset;
   if(dwSerialNumberOffset==0) return {};
   const char* serialNumber= reinterpret_cast<const char*>(pOutBuffer.get() + dwSerialNumberOffset);
   return serialNumber;
}

void printPhysicalDriversSerial() {
   bitset<32> drives(GetLogicalDrives());
   vector<char> goodDrives;
   for (char c = 'A'; c <= 'Z'; ++c) {
       if (drives[c - 'A']) {
           //if (GetDriveType((c + string(":\\")).c_str()) == DRIVE_FIXED) { descomentar para solo obtener los Discos físicos internos.
               goodDrives.push_back(c);
           //}
       }
   }
   for (auto & drive : goodDrives) {
       string s = string("\\\\.\\") + drive + ":";
       HANDLE h = CreateFileA(
           s.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
           OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL
       );
       if (h == INVALID_HANDLE_VALUE) {
           cerr << "Drive " << drive << ":\\ cannot be opened" << endl;
           continue;
       }
       DWORD bytesReturned;
       VOLUME_DISK_EXTENTS vde;
       if (!DeviceIoControl(
           h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
           NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL
       )) {
           cerr << "Drive " << drive << ":\\ cannot be mapped into physical drive" << endl;
           continue;
       }
       for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
           wchar_t disk [MAX_PATH];
           swprintf(disk, MAX_PATH, L"\\\\.\\PhysicalDrive%d", vde.Extents[i].DiskNumber);
           string serialNumber = getFirstHddSerialNumber(disk);
           fputws ( disk, stdout );
           cout << endl;
           if(serialNumber.empty()) {
               cout << "failed to retrieve serial number" << endl;
           } else {
               cout << "serial number: " << serialNumber << endl;
           }
       }
   }
}

int main() {
   printPhysicalDriversSerial();
   return 0;
}


Para corroborar los datos pintados, ejecutar en CMD:

wmic diskdrive get Name, Manufacturer, Model, InterfaceType, MediaType, SerialNumber

Saludos.
#24
Desarrollo Web / Re: Css: Inhibir reglas
1 Febrero 2021, 08:47 AM
!important te sirve?

Código (css) [Seleccionar]
body{
font-family: verdana, arial !important;
}


También implementando la jerarquía de los selectores.

https://codepen.io/pedromarin/pen/GdejgQ

De igual forma si estas con un page builder, puedes hacer que esas paginas generadas dinámicamente (supongo) se les pueda anexar atributo extra y el CSS que afecta a dichos componentes hagan uso de ese atributo para aplicar el mismo.

https://developer.mozilla.org/es/docs/Web/CSS/Selectores_CSS

igual revisa esto por el tema de la pantalla pequeña.

https://www.regochan.com/varios/item/95-modificar-css-segun-el-tamano-de-la-pantalla-responsive.html

https://www.w3schools.com/cssref/css3_pr_mediaquery.asp

saludos.
#25
El tema es solo de Accesos, si se requiriera algo de seguridad (mayor nivel), cifrado o X es mejor AES 128 (Estándar mínimo para codificación en bancos) o superior (AES 256, 1024, etc, el numero 128 es la longitud de la clave compartida en este caso 128/8 = 16 caracteres, en fin que si con salt se complica y ya mínimo requieres mas de 4 años por decir algo pero aquí lo dicen un poco mas con un análisis en base a números... cifrado: ¿qué tan seguro es AES?
para adivinar la cadena cifrada).

VB6 AES 256
Chilkat ActiveX Downloads (128-bit, 192-bit, and 256-bit AES encryption in ECB (Electronic Cookbook), CBC (Cipher-Block Chaining), and other modes)

o cualquier otro algoritmo:

VB6 lista de algoritmos para cifrar

Habitualmente es mejor programar esto en capas/fases y no mezclar todo, de tal manera que se pueda rehusar y entender.

Por cierto...

Código (vb) [Seleccionar]

Do While (TimEspera.Enabled = True): Loop


Mejor.

Código (vb) [Seleccionar]

Private Declare Function WaitMessage Lib "user32" () As Long
....

Do While (TimEspera.Enabled = True)
   doevents
   Call WaitMessage
Loop


Saludos.
#26
Esto va en foro de .NET

Saludos.
#27
Esto va en .NET pero yo cuando quiero hacer inserts en hilos recurro a bloqueos de registros por BDD.

Deberías usar un consecutivo o algo similar (que funcione en hilos), o bloquear el registro (solo en updates)... en fin lo que debes hacer es validar si existe el registro antes de hacer el insert por que en la BDD ya existe, revisa la restriccion 'PK__MATERIAL__CC87E127D767918D' en tu BDD y revisa que campos ya se han ingresado.

Algo de código que yo uso en ocasiones para mitigar esto (En Oracle):

por ejemplo en Updates

Código (sql) [Seleccionar]

DECLARE
  CURSOR c1 IS SELECT empno, job, sal FROM emp FOR UPDATE;
BEGIN
  OPEN c1;
  LOOP
     FETCH c1 INTO bla bla bla
     UPDATE emp
     SET sal = new_sal
     WHERE CURRENT OF c1;
  END LOOP;
  CLOSE c1;
END;


En cuanto a INSERTS

uso un insert con una subquery (Se requieren índices para que sea "rápida").

Código (sql) [Seleccionar]

INSERT INTO A
SELECT
   'valor 1' as campo1,
   'valor 2' as campo2,
   'valor 3' as campo3
FROM DUAL
WHERE NOT EXISTS (
   SELECT * FROM A
   WHERE A.campo1 = 'valor 1' AND A.campo2 = 'valor 2' AND A.campo2 = 'valor 2';
)


o con un MERGE (Emulando 1 tabla), (Se requieren índices para que sea "rápida").

Código (sql) [Seleccionar]

MERGE INTO A target
USING (
SELECT
'valor 1' as campo1,
'valor 2' as campo2,
'valor 3' as campo3
FROM DUAL
) src
ON target.campo1 = src.campo1, target.campo2 = src.campo2, target.campo3 = src.campo3
WHEN MATCHED THEN
UPDATE SET target.campo1 = 'valor 1', target.campo2 = 'valor 2', target.campo3 = 'valor 3'
WHEN NOT MATCHED THEN
INSERT (campo1, campo2, campo3)
VALUES ('valor 1', 'valor 2', 'valor 2');


Saludos.
#28
Es mejor usar SQLite que esto, pues no muy "legible".

http://leandroascierto.com/blog/vbsqlite3/

saludos.
#29
Si es posible pero al igual que en C/C++ en VB6 hay que usar WinAPI

https://stackoverflow.com/questions/15756386/vb6-wh-getmessage-message-hook

Cuando identifiques el mensaje WM_ACTIVATE (https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-activate) puedes identificar que esta activa tu ventana.

Usa el buscador y busca sobre Hook en VB6 hay mucho de esto.

Saludos.

#30
Programación Visual Basic / Re: soap generico
19 Diciembre 2020, 08:24 AM
Cita de: Serapis en 29 Noviembre 2020, 16:46 PM
Con toda la diversificación de tecnologías, realmente crees que va a existir una librería "que sirva para todos los servicios web del mundo" ???. Es muy ingenuo por tu parte...

ejem ejem para SOAP/Rest si ejem ejem de hecho eso mismo me dije que ingenuo soy pero me puse a leer un poco los RFC de la 3w y vi que todo era solo ''texto'' (Hablando de forma abstracta) enviado por un protocolo X... y es que necesitaba hacer en donde laboro un "Consumidor" de servicios genérico que ejecutara cualquier tipo de servicio REST/SOAP bajo HTTP/HTTPS, vaya cada 2 semanas los modifican (a;adiendo o removiendo que no se deciden los tipos) y necesitaba ser lo mas eficiente posible en ver mis series y tener poco estrés laboral y si estuviera recodificando los clientes a cada momento se me acumularían cada 15 días que me llegara algo a consumir.

El truco esta en usar SOCKETS y conectarte al servicio como un vil cliente HTTP/HTTPS y enviar peticiones viles como un cliente común y corriente después parseas los datos obtenidos con un parser XML o JSON o el tipo de dato que envies y con eso ya tienes un cliente GENERICO de servicios WEB.

Esta es mi versión para JAVA (Nunca quise manejar JAVA pero es el lenguaje que ya me da de comer), se que es un foro de VB6 al rato me instalo el VB6 y genero una versión pero igual les sirve para entender el protocolo de servicios SOAP por que a la primera asusta...

La siguiente clase la hice de esta forma y no use FRAMEWORKS de JAVA por que los frameworks no me permitían capturar los request/response de un POOL de hilos ya que compartían el mismo cache haci que me tuve que bajar a crear mi cliente pero que no estuviera bajo JAXB ya que de igual forma requería tener una catalogo de endpoints, describir los métodos en BDD etc, etc, en fin que es genérico hoy en día y consume lo que desee en la secuencia que desee a tal grado que puedo consumir un servicio mas rápido que con los frameworks, en fin solo les comparto esta clase el resto es a imaginación, obviamente el request y response se manejan en otras clases las cuales no axeso por que no es el tema de mis parsers.

Debajo del código describo como funciona.

Código (java) [Seleccionar]


package mx.com.common.service;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.rmi.RemoteException;
import java.util.Date;
import java.util.Date;

import javax.annotation.Generated;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import mx.com.common.utils.ElapseTime;

/**
* Clase para generar clientes a SOAP
*
* @author Miguel Angel Ortega Avila
*/
@SuppressWarnings("all")
public class SoapServiceClient implements ServiceClient {

private final static Logger LOG = LogManager.getLogger(SoapServiceClient.class);

private String user;
private final String pass;
private final String endpoint;
private final ElapseTime elapseTime;

private static SSLSocketFactory sslSocketFactory;

private int timeout;
private Date startTime = null;
private SOAPBody currentBody;
private String currentRequest;
private String currentResponse;

@Generated("SparkTools")
public SoapServiceClient(String user, final String pass, final String endpoint, final int timeout) {
this.endpoint = endpoint;
this.user = user;
this.pass = pass;
this.elapseTime = ElapseTime.getInstance();
this.timeout = timeout;
}

public String getCurrentRequest() {
return currentRequest;
}

public String getCurrentResponse() {
return currentResponse;
}

public SOAPMessage execute(String request) throws RemoteException {
URL url;
URLConnection conexion = null;
currentRequest = request;
currentResponse = null;
try {
elapseTime.start();
startTime = new Date();
url = new URL(this.endpoint);
conexion = url.openConnection();
if (url.getProtocol().equalsIgnoreCase("https")) {
((HttpsURLConnection) conexion).setSSLSocketFactory(sslSocketFactory);
}
((HttpURLConnection) conexion).setRequestProperty("Content-Type", "text/xml");
((HttpURLConnection) conexion).setRequestMethod("POST");
((HttpURLConnection) conexion).setConnectTimeout(this.timeout);
((HttpURLConnection) conexion).setReadTimeout(this.timeout);
} catch (final MalformedURLException e) {
throw new RemoteException("WS-SOAPService - Endpoint erroneo", e);
} catch (final ProtocolException e) {
throw new RemoteException("WS-SOAPService - Error al consumir servicio", e);
} catch (final IOException e) {
throw new RemoteException("WS-SOAPService - Error al consumir servicio", e);
}

HttpURLConnection httpURLConnection = (HttpURLConnection) conexion;
conexion.setDoOutput(true);
OutputStreamWriter out = null;
StringBuilder sb = new StringBuilder();
int returnCode;
BufferedReader buff = null;
try {
// Obligatorio para algunas versiones de SOAP (Emulacion).
httpURLConnection.setRequestProperty("SOAPAction", "");
out = new OutputStreamWriter(httpURLConnection.getOutputStream());
out.write(request);
out.flush();
returnCode = httpURLConnection.getResponseCode();
InputStream conexionIn;
if (returnCode >= 200 && returnCode < 300) {
conexionIn = httpURLConnection.getInputStream();
} else {
conexionIn = httpURLConnection.getErrorStream();
}
buff = new BufferedReader(new InputStreamReader(conexionIn));
String inputline;
while ((inputline = buff.readLine()) != null) {
sb.append(inputline);
}
httpURLConnection.disconnect();
currentResponse = sb.toString();
} catch (final SocketTimeoutException e) {
throw new RemoteException(e.getMessage(), e);
} catch (final IOException e) {
throw new RemoteException(e.getMessage(), e);
} finally {
elapseTime.stop();
if (buff != null)
try {
buff.close();
} catch (IOException e) {
LOG.error("WS-SOAPService - Error al cerrar Stream", e);
}
if (out!= null) {
try {
out.close();
} catch (IOException e) {
LOG.error("WS-SOAPService - Error al cerrar Stream", e);
}
}
}
InputStream is = new ByteArrayInputStream(sb.toString().getBytes());
SOAPMessage soapResponse;
SOAPPart part;
SOAPEnvelope env;
SOAPBody body;
SOAPHeader head;
try {
soapResponse = MessageFactory.newInstance().createMessage(null, is);
soapResponse.removeAllAttachments();
part = soapResponse.getSOAPPart();
part.detachNode();
env = part.getEnvelope();
env.detachNode();
body = env.getBody();
body.detachNode();
head = env.getHeader();
if (head != null)
head.detachNode();
} catch (final IOException e) {
throw new RemoteException("(HTTP " + returnCode + ") - " + e.getMessage(), e);
} catch (final SOAPException e) {
throw new RemoteException("(HTTP " + returnCode + ") - " + e.getMessage(), e);
} finally {
if (is != null)
try {
is.close();
} catch (IOException e) {
LOG.error("WS-SOAPService - Error al cerrar Stream", e);
}
}
if (body != null && body.hasFault()) {
throw new RemoteException(body.getFault().getTextContent(), null);
}
return soapResponse;
}

public String getHeaderSecurityXML() {
StringBuilder strbl = new StringBuilder();
strbl.append(
"<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:SOAP-ENV=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" SOAP-ENV:encodingStyle=\"\" actor=\"\" mustUnderstand=\"0\" SOAP-ENV:mustUnderstand=\"0\">");
strbl.append(
"<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:id=\"UsernameToken\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">");
strbl.append(
"<wsse:Username xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">");
strbl.append(user).append("</wsse:Username>");
strbl.append(
"<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">");
strbl.append(pass).append("</wsse:Password>");
strbl.append("</wsse:UsernameToken>");
strbl.append("</wsse:Security>");
return strbl.toString();
}

public String getUser() {
return user;
}

public String getPass() {
return pass;
}

public int getTimeout() {
return timeout;
}

@Override
public long getElapsedTime() {
return this.elapseTime.getElapsedTime();
}

@Override
public Date getStartTime() {
return this.startTime;
}
}



La teoría es la siguiente para vb6 y cualquier lenguaje.

Necesitamos un cliente básico para HTTP/HTTPS o el protocolo transporte, simularlo con sockets o alguna librería básica (https://www.chilkatsoft.com/refdoc/xChilkatHttpResponseRef.html) que permita este protocolo del servicio SOAP.

El resto ya es solo trabajo de los Request y Response

(Instalar la versión Open Source)
https://www.soapui.org/downloads/soapui/

Si se desea consumir un servicio SOAP solo debemos conocer el request y response (Usaremos SOAPUI para esto, explicar aquí el formato es complicado por ello es mejor usar esta herramienta, solo hay que ir a File -> New Soap Project ingresar el endpoint y consumes un método del servicio para obtener el request).

Una vez obtenido el request solo hay que enviarlo por nuestro cliente en vb6.

Si deseamos anexar usuario y contraseña se debe poner los siguientes headers a el request (wsse:Username y wsse:Password):

El método del Enpoint se debe consumir de la siguiente forma suponiendo que el endpoint es:

http://www.webservicex.net/globalweather.asmx?wsdl
y tiene dos métodos llamados
hola1
metodoX

y quiero llamar a metodoX

Se llamaría bajo HTTP
Se consume bajo POST
Anexar a la llamada el header "Content-Type" con el valor "text/xml"
Anexar a la llamada el header "SOAPAction" con valor vacío ""
Envio el request siguiente el cual indica que se debe ejecutar "metodoX"

Código (xml) [Seleccionar]

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mod="http://blackzerox.com.mx">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:SOAP-ENV="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:encodingStyle="" actor="" mustUnderstand="0" SOAP-ENV:mustUnderstand="0">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:id="UsernameToken" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Username xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">BlackZeroX</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">MiContrasenia123456789</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<mod:metodoX>
<objeto1>
<campo1></campo1>
<campo2></campo2>
<objetoAnidado>
<objetoAnidadoID></objetoAnidadoID>
</objetoAnidado>
<systemId></systemId>
</objeto1>
<nombre>Miguel Angel</nombre>
<apellidoM>Avila</apellidoM>
<apellidoP>Ortega</apellidoP>
<expresiones>
<suma>
<![CDATA[
1+5
]]>
</suma>
<default>
<![CDATA[
<8)
]]>
</default>
<obsolete>no</obsolete>
<value>69</value>
</expresiones>
</mod:metodoX>
</soapenv:Body>
</soapenv:Envelope>


y al enviar por sockets responderia algo asi

Código (xml) [Seleccionar]

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<metodoXResponse xmlns="http://blackzerox.com.mx">
<Response xmlns=">
<productOrderID></productOrderID>
<responseStatus>
<rejectCode>XXX</rejectCode>
<rejectDescription>descripcion XXX metodoX</rejectDescription>
<status>true</status>
</responseStatus>
</Response>
</metodoXResponse>
</soapenv:Body>
</soapenv:Envelope>


Si puedo hacer correr un día de estos en mi equipo VB6 armo un cliente genérico en VB6.

SOAP y REST son bajo la misma teoria... o muy parecida.

Saludos.